首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django ChoiceField总是无效或空的

Django ChoiceField总是无效或空的
EN

Stack Overflow用户
提问于 2018-05-15 09:47:05
回答 3查看 2.2K关注 0票数 0

我有一个表单中的ChoiceField,并希望将它的值保存在模型中。问题是,如果需要字段,表单就永远无效。当我将必需设置为False时,表单是有效的,但不包含任何数据--它只是空白。

models.py:

代码语言:javascript
复制
class CVSS(models.Model):
    av = models.CharField(
        max_length=10,
        null=True,
    )

forms.py:

代码语言:javascript
复制
class CVSSForm(forms.ModelForm):
    AV = [
        (u'N', u'Network'),
        (u'A', u'Adjacent'),
        (u'L', u'Local'),
        (u'P', u'Physical'),
    ]
    av = forms.ChoiceField(
        # required=False,
        widget=forms.RadioSelect(),
        choices=AV,
    )
    class Meta:
        model = CVSS
        fields = ['av',]

views.py:

代码语言:javascript
复制
def edit(request, fid):
    cvss = get_object_or_404(CVSS, finding_id=fid)
    cvss_form = CVSSForm(instance=cvss)
    if request.method == 'POST':
        cvss_form = CVSSForm(request.POST, instance=cvss)
        if cvss_form.is_valid():
            cvss_form.save()

edit.html:

代码语言:javascript
复制
<div class="table-responsive">
     {% include "dojo/form_fields.html" with form=cvss_form %}
</div>

表单是从form_fields.html呈现的:

代码语言:javascript
复制
{% elif field|is_radio %}
    {% if field.auto_id %}
        <label class="col-sm-4 control-label {% if field.field.required %}{{ form.required_css_class }}{% endif %}">
            {{ field.label }}{% if field.field.required%}<sup>*</sup>{% endif %}
        </label>
    {% endif %}
    <div class="col-sm-8 {{ classes.value }}">
        {% for choice in field %}
            <div class="radio">
                <label>
                    {{ choice.tag }}
                    {{ choice.choice_label }}
                </label>
            </div>
        {% endfor %}

        {% for error in field.errors %}
            <span class="help-block {{ form.error_css_class }}">{{ error }}</span>
        {% endfor %}

        {% if field.help_text %}
            <i class="fa fa-question-circle has-popover" data-trigger="hover" data-content="{{ field.help_text }}" data-placement="right" data-container="body">
            </i>
        {% endif %}
    </div>
{% else %}
EN

回答 3

Stack Overflow用户

发布于 2018-05-15 10:00:18

您可以按以下方式更改模型和表单

models.py

代码语言:javascript
复制
class CVSS(models.Model):
    AV_CHOICES = AV = [
        (u'N', u'Network'),
        (u'A', u'Adjacent'),
        (u'L', u'Local'),
        (u'P', u'Physical'),
    ]
    av = models.CharField(
        choices=AV_CHOICES
        max_length=1,
        null=True,
    )

forms.py

代码语言:javascript
复制
class CVSSForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
         super(CVSSForm, self).__init__(*args, **kwargs)
         self.fields['av'].widget = forms.RadioSelect()
    class Meta:
        model = CVSS
        fields = ['av',]

views.py

代码语言:javascript
复制
def edit(request, fid):
    cvss = get_object_or_404(CVSS, finding_id=fid)
    cvss_form = CVSSForm(instance=cvss)
    if request.method == 'POST':
        cvss_form = CVSSForm(instance=cvss, data=request.POST)
        if cvss_form.is_valid():
            cvss_form.save()

template.html

代码语言:javascript
复制
   {{ form }}
票数 2
EN

Stack Overflow用户

发布于 2018-05-15 10:04:52

你说过

如果需要该字段,则该表单永远无效。

这里所要求的术语是矛盾的。Django有两个不同的选择配置必需字段或可选字段。

如果是True,Django将将空值作为NULL存储在数据库中。默认是假的。

Null属性用于控制在数据库级别上声明字段的方式。Django doc还明确指出:

避免在基于字符串的字段(如CharField和TextField )上使用null。如果一个基于字符串的字段有null=True,这意味着它有两个可能的值: no data : NULL和空字符串。在大多数情况下,对于no数据有两个可能的值是多余的;Django约定是使用空字符串,而不是NULL。一个例外是当一个CharField同时设置了unique=True和blank=True。在这种情况下,在保存具有空值的多个对象时,需要null=True来避免唯一的约束冲突。

此外,另一个字段控制Django本身如何对链接到此模型字段的表单字段执行验证:

空白 如果为真,则允许字段为空。默认是假的。

再一次,Django doc带来了一些额外的信息

请注意,这与null不同。null是纯数据库相关的,而空白是与验证相关的。如果字段有blank=True,表单验证将允许输入空值。如果字段具有blank=False,则需要该字段。

票数 0
EN

Stack Overflow用户

发布于 2022-06-08 15:04:16

我遇到了同样的问题。当我打印出request.POST时,我可以验证MultipleChoiceField的数据是否被传输。但是当我手动选择它(request.POST“字段名”)时,它只输出最后一个元素。

我很确定有一个序列化问题,信息会正确释放,但可能不会被接收到。来自Django的forms部件在某个地方不喜欢输出,也不会正确验证(可能它需要一个列表,但得到一个Integer?!)。在我看来,主要问题在于形式部分。就我个人而言,我还没有修复,但将尝试从上面的Charfield选择选项。不过,我认为这是一个问题,应该解决!

编辑: Charfield不适合我,因为我需要多个答案选项。

我现在已经构建了一个最小的测试,它的工作非常好。

我还找到了原因,为什么我只能得到列表中的最后一个元素:

代码语言:javascript
复制
print(request.body)

输出:长字节.+ "&fieldname=2&fieldname=3“

Django只使用最后一个。我仍然不明白为什么它在一个简单的版本中工作,为什么在更复杂的版本中按上面的方式格式化。但是,现在我有个解决办法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50347080

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档