Django ChoiceField总是无效或空

时间:2018-05-15 09:47:06

标签: python django choicefield

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

models.py:

class CVSS(models.Model):
    av = models.CharField(
        max_length=10,
        null=True,
    )

forms.py:

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:

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:

<div class="table-responsive">
     {% include "dojo/form_fields.html" with form=cvss_form %}
</div>

表单由form_fields.html呈现:

{% 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 %}

2 个答案:

答案 0 :(得分:2)

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

  

models.py

<!DOCTYPE HTML>
<html>
<head>
<script 
src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"> 
</script>
<script>
function text(btn){
    alert($(btn).prev().prev().val());
}
</script>
</head>
<body>
    <textarea>test text</textarea>
<br>
<button onclick="text(this)">text</button>
</body>
</html>
  

forms.py

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,
    )
  

views.py

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',]
  

template.html

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()

答案 1 :(得分:0)

你说

  

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

必需这个词在这里很暧昧。 Django has 2 different options配置必需的可选字段。

  

<强>空

     

如果为True,Django会将空值存储为数据库中的NULL。默认值为False。

Null属性用于控制在数据库级别声明字段的方式。 Django doc也明确表示:

  

避免在基于字符串的字段(如CharField和TextField)上使用null。如果基于字符串的字段具有null = True,则表示它有两个可能的值“无数据”:NULL和空字符串。在大多数情况下,“无数据”有两个可能的值是多余的; »Django约定是使用空字符串,而不是NULL。一个例外是CharField同时具有unique = True和blank = True。在这种情况下,需要null = True以避免在使用空值保存多个对象时发生唯一约束违规。

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

  

<强>空白

     

如果为True,则允许该字段为空。默认值为False。

再次Django doc brings some additional information

  

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