Django设置类<;ul>;而不是<;输入>;使用CheckboxSelectMultiple小部件

Django设置类<;ul>;而不是<;输入>;使用CheckboxSelectMultiple小部件,django,django-forms,Django,Django Forms,我可以用如下行设置小部件的类 self.widget = forms.CheckboxSelectMultiple(attrs={'class': 'myclass'}) 但这将myclass应用于所有元素,例如 <ul> <label><li><input type="checkbox" class="myclass">1</li></label> <label><li><i

我可以用如下行设置小部件的类

self.widget = forms.CheckboxSelectMultiple(attrs={'class': 'myclass'})
但这将
myclass
应用于所有
  • 元素,例如

    <ul>
        <label><li><input type="checkbox" class="myclass">1</li></label>
        <label><li><input type="checkbox" class="myclass">2</li></label>
        <label><li><input type="checkbox" class="myclass">3</li></label>
    </ul>
    
    • 一,
    • 二,
    • 三,

    如何仅将类应用于
    元素?

    默认情况下,无法在ul标记上设置属性。“简单”的方法是将复选框selectmultiple子类化,以执行您想要的操作。两种方法是:

    使用“ulattrs”参数构造复选框SelectMultiple的自定义版本

    class MyCheckboxSelectMultiple(CheckboxSelectMultiple):
        def render(self, name, value, ulattrs=None, attrs=None, choices=()):
            if value is None: value = []
            has_id = attrs and 'id' in attrs
            final_attrs = self.build_attrs(attrs, name=name)
            output = [u'<ul class="%s">' % ulattrs.get('class')]
            # Normalize to strings
            str_values = set([force_unicode(v) for v in value])
            for i, (option_value, option_label) in enumerate(chain(self.choices, choices)):
                # If an ID attribute was given, add a numeric index as a suffix,
                # so that the checkboxes don't all have the same ID attribute.
                if has_id:
                    final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i))
                    label_for = u' for="%s"' % final_attrs['id']
                else:
                    label_for = ''
    
                cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
                option_value = force_unicode(option_value)
                rendered_cb = cb.render(name, option_value)
                option_label = conditional_escape(force_unicode(option_label))
                output.append(u'<li><label%s>%s %s</label></li>' % (label_for, rendered_cb, option_label))
            output.append(u'</ul>')
            return mark_safe(u'\n'.join(output))
    
    分类MyCheckboxSelectMultiple(CheckboxSelectMultiple):
    def render(self、name、value、ulattrs=None、attrs=None、choices=()):
    如果值为None:value=[]
    在属性中有\u id=attrs和'id'
    final\u attrs=self.build\u attrs(attrs,name=name)
    输出=[u'
      '%ulattrs.get('class')] #规范化为字符串 str_values=set([force_unicode(v)表示值中的v]) 对于枚举(链(self.choices,choices))中的i(选项值,选项标签): #如果给定了ID属性,请添加数字索引作为后缀, #因此,复选框不都具有相同的ID属性。 如果您有您的id: final_attrs=dict(final_attrs,id='%s_%s'(attrs['id'],i)) label_for=u'for=“%s”'%final_attrs['id'] 其他: 标签_为=“” cb=CheckboxInput(最终属性,检查测试=lambda值:str值中的值) 选项\u值=强制\u unicode(选项\u值) rendered\u cb=cb.render(名称、选项\u值) 选项标签=条件转义(强制unicode(选项标签)) output.append(u'
    • %s%s
    • '%(标签、呈现的cb、选项标签)) output.append(u'
    ') 返回标记\u safe(u'\n'.连接(输出))
    或者,你可以做一些更粗糙的事情

    class MyCheckboxSelectMultiple(CheckboxSelectMultiple):
        def render(self, name, value, attrs=None, choices=()):
            html = super(MyCheckboxSelectMultiple, self).render(name, value, attrs, choices)
    
            return mark_safe(html.replace('<ul>', '<ul class="foobar">'))
    
    分类MyCheckboxSelectMultiple(CheckboxSelectMultiple):
    def render(self、name、value、attrs=None、choices=()):
    html=super(MyCheckboxSelectMultiple,self).render(名称、值、属性、选项)
    返回mark_safe(html.replace(“
      ”,“
        ”)
    在Koblas的基础上,另一种更通用的方法是:

    class CheckboxSelectMultipleULAttrs(forms.CheckboxSelectMultiple):
        """
        Class to allow setting attributes on containing ul in a CheckboxSelectMultiple
        """
        def __init__(self, ulattrs=None, attrs=None, choices=()):
            self.ulattrs = ulattrs
            super(CheckboxSelectMultipleULAttrs, self).__init__(attrs, choices)
            return
    
        def render(self, name, value, attrs=None, choices=()):
            html = super(CheckboxSelectMultipleULAttrs, self).render(name, value, attrs, choices)
            if not self.ulattrs:
                return html
            return mark_safe(html.replace('<ul>', '<ul ' + self.ulattrs + '>'))
    
    类checkboxselectmultiplelattrs(forms.CheckboxSelectMultiple):
    """
    类以允许在复选框SelectMultiple中设置包含ul的属性
    """
    定义初始化(self,ulattrs=None,attrs=None,choices=()):
    self.ulattrs=ulattrs
    超级(复选框选择多个属性,自我)。\uuuu初始化(属性,选项)
    返回
    def render(self、name、value、attrs=None、choices=()):
    html=super(复选框selectmultipleulattrs,self).render(名称、值、属性、选项)
    如果不是self.ulattrs:
    返回html
    返回mark_safe(html.replace(“
      ”,“))
    我想我找到了答案:你不能。在[django/forms/widgets.py][1]中查看,呈现方法似乎通过以下方式生成其输出:从
    output=[u'
      ']
    开始,并为给定查询集中的每个元素追加一个选项
    output.append(u'
  • %s%s
  • '%(label\u for,rendered\u cb,option\u label))
    。因此,
    标记是硬编码的,我唯一的选择是创建一个自定义小部件。[1] :取决于硬编码的实施细节,将来可能会影响您。;-)据我所知,这个骇人的解决方案是完美的。我是否没有看到一些潜在的陷阱?不应该是任何陷阱。作为一个小小的警告,我从内存中编写了示例代码,但它没有在任何地方运行。我尝试在我的应用程序中实现您的黑客解决方案,但我收到了以下错误:“无法导入setting.views.location.View在module setting.views中不存在。”我在中提出了一个问题,所以也请参考这一点,你一定会给我我相信的解决方案。我没有足够的声誉来奖励这个问题的赏金,否则我这样做会得到不同的答案,我会得到感谢黑客解决方案从Django 1.6开始不起作用,
    现在看起来像
    这种“简单”的DOM更改在Django中非常糟糕,只要替换为
    replace('