带有 SelectMultiple 小部件的 MultipleChoiceField “值 [...] 不是有效选择。”
Posted
技术标签:
【中文标题】带有 SelectMultiple 小部件的 MultipleChoiceField “值 [...] 不是有效选择。”【英文标题】:MultipleChoiceField with SelectMultiple widget "Value [...] not a valid choice." 【发布时间】:2011-05-11 02:03:25 【问题描述】:我的模型中定义了一个字段-
languages = models.CharField(max_length = 30, choices=LANGUAGE_CHOICES, blank = True, null = True)
选择很简单-
LANGUAGE_CHOICES = (
('English', 'English'),
)
我在这个模型上定义了一个 ModelForm 并覆盖了字段-
languages = forms.MultipleChoiceField(choices=LANGUAGE_CHOICES, widget=forms.SelectMultiple)
当我填写表格时,选择“英文”,然后尝试提交,我得到一个错误-
语言 值 u"[u'English']" 不是一个有效的选择
我做错了什么基本的事情吗?或者 MultipleChoiceField 与 SelectMultiple 小部件结合不是可行的方法?
另外,为什么选择元组不能有两次相同的值,就像我现在有它一样('English','English')?
这里有一些额外的代码可能有助于深入了解这一点
模板代码:
<div class="abovepad">
<label for="id_languages">Languages:</label>
form.languages
</div>
POST 数据的语言部分:
u'languages': [u'English'],
ModelForm相关sn-p代码:
class ProfileForm(forms.ModelForm):
languages = forms.MultipleChoiceField(choices=LANGUAGE_CHOICES)
class Meta:
model = Student
如你所见,我几乎没有定制任何东西。过去,当我遇到这个问题时,我会切换到将列表中的项目转换为模型,然后使用不会导致相同问题的 ManyToMany 字段。对于这些情况,让项目成为模型是有意义的;在这种情况下它没有。我只想知道我是否做错了什么,或者这个组合是否应该起作用。如果没有真正的答案,那么我的另一个选择是尝试挖掘 Django 表单代码,看看它为什么会这样做。
【问题讨论】:
【参考方案1】:错误消息表明languages
不包含数组,而是包含包含该数组表示的 unicode 字符串。 languages
应计算为 [u'English']
(数组),但计算结果为 u"[u'English']"
(unicode 字符串)。
您的 ModelForm 是否包含任何可能会更改 languages
值的自定义验证(例如,clean_languages
函数)?
顺便说一句:SelectMultiple
已经是 MultipleChoiceField
的默认小部件,因此无需指定小部件。
一些有助于找到原因的事情:
呈现表单的模板代码 表单返回的POST
数据
用于 ModelForm 类的代码
【讨论】:
感谢乔丹,您的及时回复。我在上面发布了相关的信息。我的 ModelForm 不包含任何额外的内容,不幸的是,摆脱显式的小部件参数也无济于事。在我看来,Django 表单验证代码出于某种原因将 POST 数据中的数组转换为字符串...【参考方案2】:我知道这一点已经一年多了,但我认为尝试回答可能仍然会有所帮助。
我认为这里可能存在几个问题,但主要问题是 ModelForm 期望数据库记录的键而不是字符串值。
如果您制作的表单与您的数据库无关,我建议您制作表单而不是 ModelForm。但是,如果您确实想与数据库进行交互,请使用 ModelForm 并在 Student 模型中定义一个 ForeignKey 以与语言表相关联,让 ModelForm 为您完成工作。
基于我对您的模型的假设的示例应用。
your_project/example_app/models.py:
from django.db import models
class Student(models.Model):
name = models.CharField(max_length=255)
language = models.ForeignKey('Language')
class Language(models.Model):
name = models.CharField(max_length=255)
your_project/example_app/forms.py:
from django.forms import ModelForm
from example.models import Student
class StudentForm(ModelForm):
class Meta:
model = Student
相关文档:https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#modelform
sn-p:
如您所料,ForeignKey 和 ManyToManyField 模型字段类型是特殊情况:
ForeignKey 由
django.forms.ModelChoiceField
表示,它是一个ChoiceField,其选择是一个模型QuerySet。 ManyToManyField 由django.forms.ModelMultipleChoiceField
表示,它是一个MultipleChoiceField,其选择是一个模型QuerySet。
【讨论】:
+1 对于文档中的 sn-p,它帮助我解决了一个不相关的问题,因为在ManyToManyField
上意外使用了 ModelChoiceField
而不是 ModelMultipleChoiceField
。【参考方案3】:
您必须从您的模型 定义中删除choices=LANGUAGE_CHOICES
:
您的表单返回的是所选值的列表,这在您的 models.LANGUAGE_CHOICES
中不存在
【讨论】:
我很惊讶这个答案没有得到应有的关注。我遇到了与 OP 完全相同的问题,这个答案为我节省了数小时的调试时间!以上是关于带有 SelectMultiple 小部件的 MultipleChoiceField “值 [...] 不是有效选择。”的主要内容,如果未能解决你的问题,请参考以下文章
带有下拉列表的android按钮小部件,这个特定小部件的名称是啥?