Python Django小部件覆盖模板

Python Django小部件覆盖模板,python,django,widget,Python,Django,Widget,我刚到django 我想创建一个自定义小部件 forms.py: from project.widgets import MultiChoiceFilterWidget class CustomSearchForm(FacetedSearchForm): TEST_COLORS = [ u"Blau", u"Rot", u"Gelb" ] color = forms.MultipleChoiceField( label=_("Color

我刚到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'
项目/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版:

在中,我们可以找到以下内容:

Django 1.11中的新增功能:

在旧版本中,小部件是使用Python呈现的。本文档中描述的所有API都是新的

通过查看,特别是
输入
小部件如何扩展
小部件
类,我们可以看到您只需要按如下方式自定义小部件:

class MultiChoiceFilterWidget(forms.widgets.CheckboxSelectMultiple):
    template_name = 'project/widgets/filter.html'

这是您已经拥有的。

您必须执行以下步骤来呈现新的小部件模板:

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))
1) 将“django.forms”添加到已安装的应用程序中

2) 将FORM\u RENDERER='django.forms.renderers.templateSetting'添加到settings.py


更多详细信息:

如果您只需要更改模板,那么重新定义一个完整的小部件是一件乏味的事情。由于小部件作为实例传递给字段,因此可以实例化要使用的基本小部件,并在以后更改模板

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'

如果需要将自定义数据传递到模板,然后您必须创建一个自定义小部件。

您是如何在表单中使用此小部件的?@DanielRoseman我已经编辑了我的帖子您使用的是哪个Django版本?@SebCorbin 1.8.18您的
'project/widgets/filter.html'
的目录结构是什么?它需要是
返回mark\u safe(render\u to\u string(self.template\u name))
如果我没有弄错的话。如果@jhrr是真的,我会修复它。这应该是公认的答案。使用这些设置,您只需将小部件的
.html
文件放入
模板/django/forms/widgets
中,它将在返回到djangos默认值之前使用这些文件。@biodiv完成这些步骤后,您可以将替换模板实例放在项目查找模板的任何位置。不仅仅是它所寻找的镜像原始路径。别忘了你安装的应用程序的顺序。你的应用程序应该在django.forms应用程序之前,以防其他人犯我同样愚蠢的错误。。。确保将文件放入
//templates/django/forms/widgets
而不是
//templates//django/forms/widgets
中。请注意,这也会影响django admin。