Django ChoiceField всегда недействителен или пуст - PullRequest
0 голосов
/ 15 мая 2018

У меня есть ChoiceField в форме и я хочу сохранить его значение в модели.Проблема в том, что форма никогда не действительна, если поле является обязательным.Когда я установил значение «Ложь», форма действительна, но не содержит никаких данных - она ​​просто пуста.

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 голосов
/ 15 мая 2018

Вы сказали

форма никогда не действительна, если поле является обязательным.

Термин требуется здесь неоднозначен. Django имеет 2 различных варианта для настройки обязательного или необязательного поля.

нуль

Если True, Django будет хранить пустые значения как NULL в базе данных. По умолчанию установлено значение False.

Атрибут Null используется для управления тем, как поле объявляется на уровне базы данных. Django doc также прямо заявляет:

Избегайте использования null для полей на основе строк, таких как CharField и TextField. Если строковое поле имеет значение null = True, это означает, что у него есть два возможных значения для «нет данных»: NULL и пустая строка. В большинстве случаев избыточно иметь два возможных значения для «нет данных; »Соглашение Django - использовать пустую строку, а не NULL. Единственным исключением является случай, когда CharField имеет уникальное = True и пустое = True. В этой ситуации null = True требуется, чтобы избежать уникальных нарушений ограничений при сохранении нескольких объектов с пустыми значениями.

Кроме того, другое поле управляет тем, как Django сам выполняет проверку поля формы, связанного с этим полем модели:

пусто

Если True, поле может быть пустым. По умолчанию установлено значение False.

Еще раз, Django doc приносит дополнительную информацию :

Обратите внимание, что это отличается от нуля. null чисто связан с базой данных, тогда как blank связан с валидацией. Если поле имеет пустое значение = True, проверка формы позволит ввести пустое значение. Если поле имеет пустое значение = False, поле будет обязательным.

0 голосов
/ 15 мая 2018

Вы можете изменить свою модель и форму, как показано ниже

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

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

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(instance=cvss, data=request.POST)
        if cvss_form.is_valid():
            cvss_form.save()

template.html

   {{ form }}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...