【问题标题】:Django MultipleChoiceField with CheckboxSelectMultiple error if only one item selected如果只选择了一项,则带有 CheckboxSelectMultiple 的 Django MultipleChoiceField 错误
【发布时间】:2014-06-23 21:50:56
【问题描述】:

我有一个标题中描述的 Django 表单。它有一组复选框。如果选择了两个或更多,则一切正常。如果只选择了一项,那么我会得到“错误列表:输入值列表”。

我检查了 self.request.POST['key'] 并注意到当我选择多个选项时,列表包含相同键(不同值)的多个条目。它只包含一个条目和一个选项(有意义)。在任何一种情况下,这些条目都是字符串,而不是 unicode 字符串或列表。

此错误是否与 MultipleChoiceField 相关?

代码:

 # getAllChoices() returns a List([u'key', u'value'], ...)

 class TestModelForm(forms.Form):
      choices = MultipleChoiceField(label='Test Choices',
                                     choices=getAllChoices(),
                                     help_text="Testing help text",
                                     required=False,
                                     widget=CheckboxSelectMultiple())

更新:

在表单的后处理程序中,如果我手动添加第二个项目,那么一切都会再次运行。我真的在想 MultipleChoiceField 需要 >1 个项目,但我在任何地方都找不到这个记录,如果这样做是没有意义的。

以下“hack”通过附加重复项来修复它,但这不是一个可接受的解决方案。

 tmpList = self.request.POST.getall('installed_apps')
 if len(tmpList) == 1:
         self.request.POST.add('installed_apps', tmpList[0])

【问题讨论】:

  • 你能发布你用来创建这个 MultipleChoiceField 的代码吗?它是否为您的错误提供了行号?您的实现似乎正在尝试对列表执行某些操作,但由于 MultipleChoiceField 标准化为 unicode 对象,因此很容易丢失带有一个或零个对象的 list。此外,请确保您正在规范化的对象实际上可以规范化为 unicode 对象。您处理一个结果与处理多个结果的方式不同吗?
  • 我添加了一些代码。仅使用 1 项调试表单数据。我在 request.POST 数据中看到了 1 项,它是 u'some_string'。我还在 Form 类的数据字段 u'some_string' 中看到它。如果我添加两个值,它们仍然是 u'some_string' 和 u'another_string'。所以我无法分辨一两个条目之间的区别。您是对的,尽管我们将其视为列表。只是 form.is_valid() 失败,只有 1 个项目。

标签: python django forms


【解决方案1】:

来自 Django 源代码:

def clean(self, value):
    if self.required and not value:
        raise ValidationError(self.error_messages['required'], code='required')
    elif not self.required and not value:
        return self.queryset.none()
    #This line is your culprit
    if not isinstance(value, (list, tuple)):
        raise ValidationError(self.error_messages['list'], code='list')

这会引发"list" 指示的错误,它应该是'Enter a list of values.',这就是您所看到的。看起来它实际上确实需要一个值列表,而一个清理后的值不是一个列表。一种尝试是在选项中创建一个额外的空白元素,并默认选择它并隐藏在表单中。这样,只要他们选择了至少一个元素,POST 就会包含两个(选择的和隐藏的),并且会验证。

否则,最好选择不同的表单元素。

希望这会有所帮助!

【讨论】:

  • 我继承了 MultipleChoiceField 并修复了它的 to_python 方法来捕获这种情况并将其他情况传递给 super 方法。这似乎工作正常。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-19
  • 1970-01-01
  • 2013-01-14
  • 1970-01-01
  • 1970-01-01
  • 2018-06-26
  • 2015-10-28
相关资源
最近更新 更多