代码之家  ›  专栏  ›  技术社区  ›  akdom

<option>使用Django Forms API对选择输入进行级别控制

  •  1
  • akdom  · 技术社区  · 17 年前

    我想使用Django Forms API将label=属性添加到Select表单输入的option元素中,而不覆盖Select小部件的render_options方法。这可能吗?如果可能,如何实现?

    注意:我想直接将标签添加到选项(此 在XHTML严格标准中有效)不是optgroup。

    2 回复  |  直到 17 年前
        1
  •  2
  •   Luper Rouch François Lagunas    17 年前

    from django.forms.widgets import Select
    from django.utils.encoding import force_unicode
    from itertools import chain
    from django.utils.html import escape, conditional_escape
    
    
    class ExtendedSelect(Select):
        """
        A subclass of Select that adds the possibility to define additional 
        properties on options.
    
        It works as Select, except that the ``choices`` parameter takes a list of
        3 elements tuples containing ``(value, label, attrs)``, where ``attrs``
        is a dict containing the additional attributes of the option.
        """
    
        def render_options(self, choices, selected_choices):
            def render_option(option_value, option_label, attrs):
                option_value = force_unicode(option_value)
                selected_html = (option_value in selected_choices) and u' selected="selected"' or ''
                attrs_html = []
                for k, v in attrs.items():
                    attrs_html.append('%s="%s"' % (k, escape(v)))
                if attrs_html:
                    attrs_html = " " + " ".join(attrs_html)
                else:
                    attrs_html = ""
                return u'<option value="%s"%s%s>%s</option>' % (
                    escape(option_value), selected_html, attrs_html,
                    conditional_escape(force_unicode(option_label)))
            # Normalize to strings.
            selected_choices = set([force_unicode(v) for v in selected_choices])
            output = []
            for option_value, option_label, option_attrs in chain(self.choices, choices):
                if isinstance(option_label, (list, tuple)):
                    output.append(u'<optgroup label="%s">' % escape(force_unicode(option_value)))
                    for option in option_label:
                        output.append(render_option(*option))
                    output.append(u'</optgroup>')
                else:
                    output.append(render_option(option_value, option_label,
                        option_attrs))
            return u'\n'.join(output)
    

    例子:

    select = ExtendedSelect(choices=(
            (1, "option 1", {"label": "label 1"}),
            (2, "option 2", {"label": "label 2"}),
        ))
    
        2
  •  1
  •   Jarret Hardie    17 年前

    如果不将 Select 小部件来提供您自己的渲染,正如您所猜测的。这个 code for Select <option>

    def render_option(option_value, option_label):
        option_value = force_unicode(option_value)
        selected_html = (option_value in selected_choices) and u' selected="selected"' or ''
        return u'<option value="%s"%s>%s</option>' % (
            escape(option_value), selected_html,
            conditional_escape(force_unicode(option_label)))