Django: How to build a custom form widget?

后端 未结 5 1586
一生所求
一生所求 2020-11-28 23:23

I am having a difficult time finding documentation on how to write a custom widget.

My questions are:

  • If I build a custom widget, can it be used equiva
5条回答
  •  一整个雨季
    2020-11-29 00:00

    Usually I start by inheriting from one of the existing widgets, add a new desired property and then modify a render method. Here's an example for a filterable select widget I implemented. The filtering is done via jquery mobile.

    class FilterableSelectWidget(forms.Select):
        def __init__(self, attrs=None, choices=()):
            super(FilterableSelectWidget, self).__init__(attrs, choices)
            # choices can be any iterable, but we may need to render this widget
            # multiple times. Thus, collapse it into a list so it can be consumed
            # more than once.
            self._data_filter = {}
    
        @property
        def data_filter(self):
            return self._data_filter
    
        @data_filter.setter
        def data_filter(self, attr_dict):
            self._data_filter.update(attr_dict)
    
        def render_option(self, selected_choices, option_value, option_label):
            option_value = force_text(option_value)
            if option_value in selected_choices:
                selected_html = mark_safe(' selected="selected"')
                if not self.allow_multiple_selected:
                    # Only allow for a single selection.
                    selected_choices.remove(option_value)
            else:
                selected_html = ''
            # use self.data_filter
            filtertext = self.data_filter.get(option_value)
            data_filtertext = 'data-filtertext="{filtertext}"'.\
                format(filtertext=filtertext) if filtertext else ''
            return format_html('',
                               option_value,
                               selected_html,
                               force_text(option_label),
                               mark_safe(data_filtertext))
    

    Then in the views where I create a form, I'll set the data_filter for the field.

            some_form.fields["some_field"] = \
                forms.ChoiceField(choices=choices,
                                  widget=FilterableSelectWidget)
            some_form.fields["some_field"].widget.data_filter = \
                data_filter
    

提交回复
热议问题