我是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'
项目/部件/ filter.html:
<h1>TEST</h1>
但它不会呈现新模板,相反它仍然呈现旧方式。
你能给我一些提示吗?
答案 0 :(得分:13)
Django版本&lt; 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中,我们可以找到以下内容:
Django 1.11中的新功能:
在旧版本中,小部件使用Python呈现。本文档中描述的所有API都是新的。
通过查看widget source code,特别是Input
窗口小部件如何扩展Widget
类,我们可以看到您只需要按如下方式自定义窗口小部件:
class MultiChoiceFilterWidget(forms.widgets.CheckboxSelectMultiple):
template_name = 'project/widgets/filter.html'
这就是你已经拥有的。
答案 1 :(得分:7)
您将必须执行以下步骤来呈现新的小部件模板:
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
答案 2 :(得分:0)
您似乎正在尝试使用仅在Django 1.11中可用的template-based widget form rendering API,或者您应该升级到Django 1.11或使用旧的方式,即overriding the render() method
答案 3 :(得分:0)
如果只需要更改模板,那么重新定义完整的窗口小部件就很繁琐。由于该窗口小部件作为实例传递给该字段,因此您可以实例化要使用的基本窗口小部件,然后更改模板。
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'
如果您需要将自定义数据传递到模板,则必须创建一个自定义小部件。