【问题标题】:MultipleChoiceField with SelectMultiple widget "Value [...] not a valid choice."带有 SelectMultiple 小部件的 MultipleChoiceField “值 [...] 不是有效选择。”
【发布时间】: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 表单代码,看看它为什么会这样做。

【问题讨论】:

    标签: django forms select django-models field


    【解决方案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 完全相同的问题,这个答案为我节省了数小时的调试时间!
    猜你喜欢
    • 2011-02-07
    • 2020-06-10
    • 2010-10-13
    • 1970-01-01
    • 1970-01-01
    • 2013-01-14
    • 1970-01-01
    • 2019-01-29
    • 1970-01-01
    相关资源
    最近更新 更多