这是在 Django 1.9 中按预期工作的代码:
class MultipleBooleanField(forms.MultiValueField):
def __init__(self, *args, **kwargs):
self.fieldnames = kwargs.pop('fields')
fields = [ forms.BooleanField(required=False) for x in self.fieldnames ]
super(MultipleBooleanField, self).__init__(fields=fields,
require_all_fields=False, *args, **kwargs)
self.widget = MultipleBooleanWidget(widgets=[ f.widget for f in fields ])
self.widget.fieldnames = self.fieldnames
def compress(self, datalist):
# return a list of the fieldnames, datalist is a list of booleans
print('compress datalist:', datalist)
if self.required and not any(datalist):
raise forms.ValidationError('You must choose at least one value')
return [ self.fieldnames[i] for i in range(len(datalist)) if datalist[i] ]
class MultipleBooleanWidget(forms.MultiWidget):
def render(self, name, value, attrs=None, renderer=None):
if not value:
value = [ False for x in self.fieldnames ]
rendered_widgets = [ x.render(name, value[i]) for i,x in enumerate(self.widgets) ]
items = [ '%s %s' % (rendered_widgets[i], f)
for (i,f) in enumerate(self.fieldnames) ]
return ' '.join(items)
def decompress(self, value):
# return a list of booleans, value is a list of fieldnames
print('decompress value:', value)
if not value:
return [ False for x in self.fieldnames ]
return [ x in value for x in self.fieldnames ]
在 Django 1.11 中,它不再有效,ValidationError 总是被引发。 datalist 始终是一个仅包含 False 的列表。 永远不会调用decompress 方法。
我尝试按照非常旧的帖子中的建议实现 value_from_datadict 方法,但没有成功。
我看了一下Djando代码,好像Django不喜欢字段的结果(compress的返回值)是一个列表,所以我试着把它转换成一个字符串(作为逗号连接值)。但行为保持不变。
有什么想法吗?
编辑: 查看 HTML 源代码,子部件似乎没有正确呈现:它们都具有相同的名称,并且没有 ID。假设字段名称是 Valeurs:
在 Django 1.9 中,HTML 是:
<tr><th><label for="id_Valeurs_0">Valeurs :</label></th><td><input checked="checked" id="id_Valeurs_0" name="Valeurs_0" type="checkbox" /> Part du total com <input checked="checked" id="id_Valeurs_1" name="Valeurs_1" type="checkbox" /> Part du total Qté <input checked="checked" id="id_Valeurs_2" name="Valeurs_2" type="checkbox" /> ...
在 Django 1.11 中,HTML 是:
<tr><th><label for="id_Valeurs_0">Valeurs :</label></th><td><input type="checkbox" name="Valeurs" checked /> Part du total com <input type="checkbox" name="Valeurs" checked /> Part du total Qté <input type="checkbox" name="Valeurs" checked />
我有其他的 MultiValueField/MultiWidget 可以正常工作,写法非常相似。我真的不明白问题出在哪里。
请您参考如下方法:
这是发行说明所说的
The Widget.format_output() method is removed. Use a custom widget template instead.
