且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Django 小部件覆盖模板

更新时间:2023-11-14 17:24:22

Django 版本

1.11:

小部件必须实现 render 方法才能渲染不同的模板:

from django.utils.safestring import mark_safe从 django.template.loader 导入 render_to_stringMultiChoiceFilterWidget 类(forms.widgets.CheckboxSelectMultiple):template_name = '项目/小部件/filter.html'def 渲染(自我,数据):...用数据做事...return mark_safe(render_to_string(self.template_name))

Django 1.11 版:

renderer 的文档中,我们可以找到以下内容:

Django 1.11 中的新功能:

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

查看 widget 源代码 特别是关于 Input 小部件如何扩展 Widget 类,我们可以看到您只需要按如下方式自定义小部件:

类 MultiChoiceFilterWidget(forms.widgets.CheckboxSelectMultiple):template_name = '项目/小部件/filter.html'

这是你已经拥有的.

I am new at django.

I want to create a custom widget.

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>

But it doesn't render the new template, instead it still renders the old way.

Can you give me some tips?

Django version < 1.11:

The widget must implement the render method in order to render a different template:

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 version 1.11:

In the renderer's documentation, we can find the following:

New in Django 1.11:

In older versions, widgets are rendered using Python. All APIs described in this document are new.

And by having a look at the widget source code and specifically on how the Input widget extends the Widget class, we can see that you would only need to customize your widget as follows:

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

Which is what you have already.