Django 小部件覆盖模板
Django widget override template
我是 django 的新手。
我想创建一个自定义小部件。
forms.py:
from project.widgets import MultiChoiceFilterWidget
class CustomSearchForm(FacetedSearchForm):
TEST_COLORS = [
u"Blau", u"Rot", u"Gelb"
]
color = forms.MultipleChoiceField(
label=_("Color"), choices=[(x, x) for x in TEST_COLORS],
widget=MultiChoiceFilterWidget, required=False)
widget.py:
class MultiChoiceFilterWidget(forms.widgets.CheckboxSelectMultiple):
template_name = 'project/widgets/filter.html'
option_template_name = 'ptoject/widgets/filter_option.html'
project/widgets/filter.html:
<h1>TEST</h1>
但它不呈现新模板,而是仍以旧方式呈现。
你能给我一些提示吗?
Django 版本 < 1.11:
小部件必须实现 render
方法才能呈现不同的模板:
from django.utils.safestring import mark_safe
from django.template.loader import render_to_string
class MultiChoiceFilterWidget(forms.widgets.CheckboxSelectMultiple):
template_name = 'project/widgets/filter.html'
def render(self, data):
...
Do stuff with data
...
return mark_safe(render_to_string(self.template_name))
Django 版本 1.11:
在renderer's documentation中,我们可以找到以下内容:
New in Django 1.11:
In older versions, widgets are rendered using Python. All APIs described in this document are new.
通过查看 widget source code,特别是 Input
小部件如何扩展 Widget
class,我们可以看出您只需要按如下方式自定义您的小部件:
class MultiChoiceFilterWidget(forms.widgets.CheckboxSelectMultiple):
template_name = 'project/widgets/filter.html'
这是你已经拥有的。
您必须执行以下步骤来呈现您的新小部件模板:
1) 将 'django.forms' 添加到您的 INSTALLED_APPS;
2) 添加 FORM_RENDERER = 'django.forms.renderers.TemplatesSetting' 到您的 settings.py.
更多详情:https://docs.djangoproject.com/en/2.0/ref/forms/renderers/#django.forms.renderers.TemplatesSetting
如果你只需要改变模板,重新定义一个完整的widget是徒劳的。由于小部件作为实例传递给字段,您可以实例化要使用的基本小部件,然后更改模板。
class CustomSearchForm(FacetedSearchForm):
TEST_COLORS = [
u"Blau", u"Rot", u"Gelb"
]
color = forms.MultipleChoiceField(
label=_("Color"), choices=[(x, x) for x in TEST_COLORS],
widget=forms.widgets.CheckboxSelectMultiple, required=False)
color.widget.template_name = 'project/widgets/filter.html'
color.widget.option_template_name = 'project/widgets/filter_option.html'
如果您需要将自定义数据传递给您的模板,则必须创建一个自定义小部件。
我是 django 的新手。
我想创建一个自定义小部件。
forms.py:
from project.widgets import MultiChoiceFilterWidget
class CustomSearchForm(FacetedSearchForm):
TEST_COLORS = [
u"Blau", u"Rot", u"Gelb"
]
color = forms.MultipleChoiceField(
label=_("Color"), choices=[(x, x) for x in TEST_COLORS],
widget=MultiChoiceFilterWidget, required=False)
widget.py:
class MultiChoiceFilterWidget(forms.widgets.CheckboxSelectMultiple):
template_name = 'project/widgets/filter.html'
option_template_name = 'ptoject/widgets/filter_option.html'
project/widgets/filter.html:
<h1>TEST</h1>
但它不呈现新模板,而是仍以旧方式呈现。
你能给我一些提示吗?
Django 版本 < 1.11:
小部件必须实现 render
方法才能呈现不同的模板:
from django.utils.safestring import mark_safe
from django.template.loader import render_to_string
class MultiChoiceFilterWidget(forms.widgets.CheckboxSelectMultiple):
template_name = 'project/widgets/filter.html'
def render(self, data):
...
Do stuff with data
...
return mark_safe(render_to_string(self.template_name))
Django 版本 1.11:
在renderer's documentation中,我们可以找到以下内容:
New in Django 1.11:
In older versions, widgets are rendered using Python. All APIs described in this document are new.
通过查看 widget source code,特别是 Input
小部件如何扩展 Widget
class,我们可以看出您只需要按如下方式自定义您的小部件:
class MultiChoiceFilterWidget(forms.widgets.CheckboxSelectMultiple):
template_name = 'project/widgets/filter.html'
这是你已经拥有的。
您必须执行以下步骤来呈现您的新小部件模板:
1) 将 'django.forms' 添加到您的 INSTALLED_APPS;
2) 添加 FORM_RENDERER = 'django.forms.renderers.TemplatesSetting' 到您的 settings.py.
更多详情:https://docs.djangoproject.com/en/2.0/ref/forms/renderers/#django.forms.renderers.TemplatesSetting
如果你只需要改变模板,重新定义一个完整的widget是徒劳的。由于小部件作为实例传递给字段,您可以实例化要使用的基本小部件,然后更改模板。
class CustomSearchForm(FacetedSearchForm):
TEST_COLORS = [
u"Blau", u"Rot", u"Gelb"
]
color = forms.MultipleChoiceField(
label=_("Color"), choices=[(x, x) for x in TEST_COLORS],
widget=forms.widgets.CheckboxSelectMultiple, required=False)
color.widget.template_name = 'project/widgets/filter.html'
color.widget.option_template_name = 'project/widgets/filter_option.html'
如果您需要将自定义数据传递给您的模板,则必须创建一个自定义小部件。