pythondjangowidget

Django widget override template


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?


Solution

  • 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.