3

我正在根据模型的数据定义一个 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 object not iterable”错误。到目前为止,我发现的唯一方法是:

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 提前谢谢。

4

2 回答 2

10

一个简单的答案是:

field = forms.ChoiceField(choices=[[0, '----------']] + [[r.id, r.name] for r in Model.objects.all()])

不幸的是,你的方法是有缺陷的。即使使用您的“工作”方法,字段选择也是在定义表单时定义的,而不是在实例化时定义的 - 因此,如果您将元素添加到模型表中,它们将不会出现在选择列表中。

__init__您可以通过在表单的方法中进行分配来避免这种情况。

但是,有一个更简单的方法。与其动态地处理字段选择,不如使用专门设计用于提供模型选择的字段 - ModelChoiceField. 这不仅在实例化时动态获取模型元素列表,而且默认情况下已经包含一个空白选项。请参阅文档

于 2009-09-16T10:08:23.990 回答
1

由于这个问题及其答案几乎解决了我刚刚遇到的一个问题,所以我想补充一点。对我来说,id 必须为空,因为模型没有将“0”识别为有效选项,但它接受了空(null=True,blank=True)。在初始化器中:

self.fields['option_field'].choices = [
    ('', '------')] + [[r.id, r.name] for r in Model.objects.all()] 
于 2017-06-12T21:53:59.570 回答