【问题标题】:Default selected options in SelectMultiple widgetSelectMultiple 小部件中的默认选定选项
【发布时间】:2020-06-10 05:48:12
【问题描述】:

我将几个forms.SelectMultiple 小部件作为呈现它们的快捷方式传递给视图。有没有办法通过默认检查哪些选项?源代码似乎不允许这样做:

class SelectMultiple(Select):
    allow_multiple_selected = True

    def render(self, name, value, attrs=None, choices=()):
        if value is None:
            value = []
        final_attrs = self.build_attrs(attrs, name=name)
        output = [format_html('<select multiple="multiple"{}>', flatatt(final_attrs))]
        options = self.render_options(choices, value)
        if options:
            output.append(options)
        output.append('</select>')
        return mark_safe('\n'.join(output))

    def value_from_datadict(self, data, files, name):
        if isinstance(data, (MultiValueDict, MergeDict)):
            return data.getlist(name)
        return data.get(name, None)

再次重申,我只是在使用小部件。它没有绑定到任何表单域,所以我不能使用initial

【问题讨论】:

  • 你还在用 Django-1.8 吗?
  • @WillemVanOnsem 不取决于我

标签: django django-1.8


【解决方案1】:

选定元素的列表在value 中。所以你可以制作一个小部件:

CHOICES = [
    ('1', 'red'),
    ('2', 'green'),
    ('3', 'blue'),
]

widget=forms.SelectMultiple()
widget.render('item-name', value=['1', '3'], choices=CHOICES)

在源代码中我们看到render_options is implemented as [GitHub]:

    def render_options(self, choices, selected_choices):
        # Normalize to strings.
        selected_choices = set(force_text(v) for v in selected_choices)
        output = []
        for option_value, option_label in chain(self.choices, choices):
            if isinstance(option_label, (list, tuple)):
                output.append(format_html('<optgroup label="{}">', force_text(option_value)))
                for option in option_label:
                    output.append(self.render_option(selected_choices, *option))
                output.append('</optgroup>')
            else:
                output.append(self.render_option(selected_choices, option_value, option_label))
        return '\n'.join(output)

render_option method [GitHub]:

    def render_option(self, selected_choices, option_value, option_label):
        if option_value is None:
            option_value = ''
        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 = ''
        return format_html('<option value="{}"{}>{}</option>',
                           option_value,
                           selected_html,
                           force_text(option_label))

因此它会检查该值是否在您传递的值列表中。

【讨论】:

  • TypeError: __init__() got an unexpected keyword argument 'value'
  • @dabadaba:对不起,当然应该传递给render方法。
猜你喜欢
  • 2011-02-07
  • 1970-01-01
  • 2012-06-24
  • 2010-10-13
  • 1970-01-01
  • 2011-05-11
  • 1970-01-01
  • 2022-01-01
  • 2017-12-18
相关资源
最近更新 更多