Django Form 将 ChoiceField 选项设置为 Form 被调用

Posted

技术标签:

【中文标题】Django Form 将 ChoiceField 选项设置为 Form 被调用【英文标题】:Django Form setting ChoiceField options as Form is called 【发布时间】:2013-06-27 20:45:49 【问题描述】:

我正在尝试与库存应用程序集成,并允许用户通过 Django 表单将零件添加到库存中。我可以从库存数据库中读取数据,但必须通过 API 进行写入,因此根据他们在之前的表单中输入的内容,我想为他们提供要添加的可用部件列表。

这是我的表单,我设置了一些默认选项:

class PartForm(forms.Form):
    PART_CHOICES = (
    ('BT-J1KND-A', 'BT-J1KND-A'),
    ('BT-J1KND-B', 'BT-J1KND-B'),)
    part = forms.ChoiceField(choices = PART_CHOICES,required = True, label = 'Part to add to Inventory')

这是我设置选项的地方

parts_list = part_sql(part)
#build choices
PART_CHOICES= [(p[0],p[0]) for p in parts_list]
form = PartForm()
form.fields['part'].choices = PART_CHOICES

它在模板中正确显示,但是当我点击保存并处理表单时,如果它不是我输入的默认选项之一,则表示它不是有效选项。

Select a valid choice. BT-J1KND-C is not one of the available choices.

如何解决此问题以使其接受我设置为有效选项的选项?

【问题讨论】:

大概有多少个零件可供选择? 【参考方案1】:

一旦请求得到处理,您的用户输入似乎会进入未经修改的PartForm,使用硬编码值。

为了正确处理请求,您需要有一个一致的PartForm

你可以通过在初始化时修改字段的choices属性来顺利实现。

例如:

class ExampleForm(forms.Form):
    CHOICES = (
        ('EXMPL', 'Example'),
    )
    field = forms.ChoiceField(choices=CHOICES, required=True, label='Example')

    def __init__(self, custom_choices=None, *args, **kwargs):
        super(ExampleForm, self).__init__(*args, **kwargs)
        if custom_choices:
            self.fields['field'].choices = custom_choices

然后,只需记住正确初始化表单,使用

form = ExampleForm(my_custom_choices_nested_tuple, ...)

您还可以仔细检查您实际处理数据的位置(我猜您复制的代码中没有提到form = PartForm(request.REQUEST)

【讨论】:

这消除了一个错误,但现在当我尝试处理数据时出现值错误。 ValueError too many values to unpack 突出显示的行是我显示 form.as_p 的模板行 哦,只是为了澄清,选择作为元组列表传递到表单中,所以我不知道问题到底出在哪里 form = PartForm(request.POST) if form.is_valid(): 总是失败 在搞砸了验证之后终于让它工作了谢谢!【参考方案2】:

如果您以编程方式更改表单上的某个字段,我相信您之后需要在表单上调用full_clean(),以便更改反映在表单中。我们在我处理的应用程序上执行此操作 - 这是我们为您的示例修改的代码。

from django.forms import Select

...

field = form.fields['part']
field.choices = PART_CHOICES
field.widget = Select(choices=PART_CHOICES)

form.fields['part'] = field
form.full_clean()

请注意,除了分配field.choices,我们还重新初始化field.widget

【讨论】:

这也消除了验证错误,但现在我有一个 ValueError 太多值无法解包 有趣,我们的其中一个应用程序运行良好,将在上面粘贴一些示例代码,以便您了解我们的解决方案与您的解决方案有何不同。 当我在 POST 请求中到达 is_valid 时出现问题,它总是返回 False....

以上是关于Django Form 将 ChoiceField 选项设置为 Form 被调用的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Django forms.ChoiceField 呈现为 Twitter Bootstrap 下拉菜单

Django 表单 ChoiceField 依赖于另一个 ChoiceField

如何在 Django 表单 ChoiceField 中获取选项标签?

Django之form

带有动态表单的 Django FormWizard

Django--Form小结