添加一个“空”基于模型数据的 ChoiceField 选项

发布于 2024-08-04 19:56:53 字数 755 浏览 3 评论 0原文

我正在根据模型的数据定义 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 提前致谢。

I'm defining a ChoiceField based on a model's datas.

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

However I'd like to prepend my options with an empty one to select "no" objects.
But I can't find a nice way to prepend that.

All my tests like :

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

Returns me a "NoneType object not iterable" error.
The only way I've found until now is the following :

def append_empty(choices):
    ret = [[0, '----------']]
    for c in choices:
        ret.append(c)
   return ret

And when I define my field :

forms.ChoiceField(choices=append_empty([[r.id, r.name] for r in
    Restaurant.objects.all()]), required=False)

However I'd like to keep my code clean and not have that kind of horrors.
Would you have an idea for me ? :p
Thanks by advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

送你一个梦 2024-08-11 19:56:53

一个简单的答案是:

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

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

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

然而,还有一种更简单的方法。您应该使用专门设计用于提供模型选择的字段 - ModelChoiceField,而不是动态地搞乱字段选择。这不仅在实例化时动态获取模型元素列表,而且默认情况下它已经包含一个空白选择。请参阅文档

An easy answer is to do:

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

Unfortunately, your approach is flawed. Even with your 'working' approach, the field choices are defined when the form is defined, not when it is instantiated - so if you add elements to the Model table, they will not appear in the choices list.

You can avoid this by doing the allocation in the __init__ method of your Form.

However, there is a much easier approach. Rather than messing about with field choices dynamically, you should use the field that is specifically designed to provide choices from a model - ModelChoiceField. Not only does this get the list of model elements dynamically at instantiation, it already includes a blank choice by default. See the documentation.

瑾夏年华 2024-08-11 19:56:53

由于这个问题及其答案几乎解决了我刚刚遇到的问题,我想添加一些内容。对我来说,id 必须为空,因为模型无法将“0”识别为有效选项,但它接受空(null=True,blank=True)。在初始化程序中:

self.fields['option_field'].choices = [
    ('', '------')] + [[r.id, r.name] for r in Model.objects.all()] 

Since this question and its answer almost solved a problem I just had I'd like to add something. For me, the id had to be empty because the model didn't recognise '0' as a valid option, but it accepted empty (null=True, blank=True). In the initializer:

self.fields['option_field'].choices = [
    ('', '------')] + [[r.id, r.name] for r in Model.objects.all()] 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文