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('