【问题标题】:Python/Django BooleanField model with RadioSelect form default to empty带有 RadioSelect 表单的 Python/Django BooleanField 模型默认为空
【发布时间】:2010-08-12 14:35:20
【问题描述】:

我正在使用 Django ModelForm,其中我的模型包含一个 BooleanField,与该 BooleanField 关联的表单小部件是 RadioSelect 小部件。我希望 RadioSelect 小部件呈现为没有选择任何选项,因此用户必须明确做出选择,但如果他们没有选择,表单验证将失败。有没有办法做到这一点?

models.py

myboolean = models.BooleanField(choices=YES_NO)

forms.py

class myModelForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(myModelForm, self).__init__(*args, **kwargs)
        self.fields['myboolean'].widget = forms.RadioSelect(choices=YES_NO)

【问题讨论】:

    标签: django widget modelform radio-button


    【解决方案1】:

    您的代码实际上可以满足您的需求。它呈现未选择任何选项的单选按钮,如果未选择任何选项,则会生成错误消息。

    关于您的表单代码的小注释。我会这样做:

    class myModelForm(forms.ModelForm):
    
        myboolean = forms.BooleanField(widget=forms.RadioSelect(choices=YES_NO))
    
        class Meta:
            model = MyModel
    

    【讨论】:

    • 谢谢安德烈。看到您的解决方案后,我重新检查了我的情况,发现我的简化示例删除了一条重要信息。已就位的 ModelField 覆盖干扰了默认值。我从这个问题中了解到 RadioSelect 字段似乎设置了 default=None 。我的替代设置是将默认值设置为 False。 (顺便说一句,我使用 init 函数是因为我不想胜过模型设置的任何默认值,例如标签)。
    • 再次感谢您对此提供的帮助,并对不好的例子表示抱歉。我试图将问题分解为核心,但错过了一些信息。
    【解决方案2】:

    不幸的是,这与其说是 Django 问题,不如说是 HTML 问题。 HTML 规范 (RFC1866) 说:

    始终只选中一组中的一个单选按钮。如果一组单选按钮的 元素都没有指定“已检查”,则用户代理必须首先检查该组的第一个单选按钮。

    但是,浏览器历来忽略了这一点,并以不同的方式实现了单选按钮。

    HTML 也使这变得困难,因为 标记的“checked”属性不带参数,因此您不能使用自定义的 Django 小部件将此属性设置为 False 或 No。

    一种可能的解决方法是放入一个小的 Javascript,它作为文档的 onLoad 事件的一部分运行,该事件会查找页面上的所有单选按钮并将“checked”属性设置为 false(例如,使用 JQuery)。

    【讨论】:

    • 我喜欢用 javascript 擦除检查值的解决方法。我唯一担心的是 Django 不会抱怨空的单选按钮框并将它们评估为假。我宁愿它抛出一个验证错误。
    • 正如 Andrey 在下面提到的,如果未选择单选按钮,那么 Django 应该抛出验证错误,因为 'required' 默认为 True。
    • 很高兴知道这一点。我不确定 BooleanField 会如何影响 RadioSelect 小部件,因为我发现很多示例都使用 IntegerField。感谢您的意见。
    【解决方案3】:
    【解决方案4】:

    我使用默认小部件创建自定义字段。

    我的models.py的剪辑:

    class Order(models.Model):
        ...
        # transport =  models.CharField(choices=transport.choices,max_length=25,null=True)
        transport = SelectField(choices=transport.choices,max_length=25,null=True)
        ...
    

    字段定义:

    from django.db import models
    from django.forms import widgets
    
    class SelectField(models.CharField):
        def formfield(self, **kwargs):
            if self._choices:
                defaults = {'widget': widgets.RadioSelect}
            defaults.update(kwargs)
            return super(SelectField, self).formfield(**defaults)
    

    【讨论】:

      猜你喜欢
      • 2015-05-05
      • 1970-01-01
      • 1970-01-01
      • 2013-12-24
      • 2020-12-04
      • 2010-12-05
      • 2011-12-24
      • 2011-07-08
      • 1970-01-01
      相关资源
      最近更新 更多