根据模型数据为ChoiceField添加一个“空”选项
我正在根据模型的数据定义一个选择字段。
field = forms.ChoiceField(choices=[[r.id, r.name] for r in Model.objects.all()])
不过,我想在选项前面加一个空选项,以便选择“没有”对象。但我找不到一个好的方法来添加这个空选项。
我尝试过的所有方法,比如:
field = forms.ChoiceField(choices=[[0, '----------']].extend([[r.id, r.name] for r in Model.objects.all()]))
都让我遇到了“NoneType对象不可迭代”的错误。到目前为止,我找到的唯一解决办法是:
def append_empty(choices):
ret = [[0, '----------']]
for c in choices:
ret.append(c)
return ret
然后当我定义我的字段时:
forms.ChoiceField(choices=append_empty([[r.id, r.name] for r in
Restaurant.objects.all()]), required=False)
不过,我想保持代码的整洁,不想让代码变得那么糟糕。你有没有什么好主意?:p 提前谢谢你。
2 个回答
1
因为这个问题和它的答案几乎解决了我刚遇到的问题,所以我想补充一点。对我来说,id必须是空的,因为模型不把'0'当作一个有效的选项,但它接受空值(null=True, blank=True)。在初始化的时候:
self.fields['option_field'].choices = [
('', '------')] + [[r.id, r.name] for r in Model.objects.all()]
10
一个简单的解决办法是这样做:
field = forms.ChoiceField(choices=[[0, '----------']] + [[r.id, r.name] for r in Model.objects.all()])
不过,你的方法有点问题。即使你的方法看起来能用,字段选项是在表单定义的时候就已经确定了,而不是在实例化的时候。所以如果你在模型表中添加了新元素,它们不会出现在选项列表里。
你可以通过在表单的 __init__
方法中进行分配来避免这个问题。
不过,还有一个更简单的方法。与其动态地调整字段选项,不如使用一个专门用来从模型中提供选项的字段——ModelChoiceField
。这个字段不仅在实例化时能动态获取模型元素的列表,而且默认情况下已经包含了一个空选项。你可以查看 文档了解更多信息。