Набор форм Django не проходит проверку даты с действительной датой

Я столкнулся с ошибкой проверки даты с использованием набора форм django. Я не получаю ту же ошибку проверки, когда я formset.is_valid(). Проблема, с которой я сталкиваюсь, заключается в том, что проверка формы is_valid не выполняется, только с использованием представления и шаблона (не в оболочке), особенно при использовании даты в форме «20 марта 2018 года», тогда как она всегда проходит с «2018-03 -20".

Также я могу проверить, что данные находятся в request.POST, но неверный ключ due_date отсутствует в self.cleaned_data, когда я ищу его в методе очистки формы. Возможно, это нормально, учитывая неверный ключ, но я ожидаю, что это произойдет после очистки, а не до, если вообще произойдет. Похоже, что это ошибка django, я на django 2.0.2

Вот краткое изложение строительства, его довольно ванильное:

# models.py
class Schedule(models.Model):
    # ...
    name = models.CharField(max_length=256)
    status = models.CharField(max_length=16, default=choices.NOT_STARTED, choices=choices.SCHEDULE_STATUSES)
    due_date = models.DateField(blank=True, null=True)
    # ...

# forms.py
class ScheduleForm(forms.ModelForm):

    class Meta:
        model = models.Schedule
        fields = ['name', 'user', 'status', 'due_date']

# views.py
def line_schedules_edit(request, line_slug):
    line = get_object_or_404(models.Line, slug=line_slug)
    queryset = line.schedules.all()

    ScheduleFormSet = modelformset_factory(models.Schedule, form=forms.ScheduleForm)

    if request.method == 'POST':
        schedules_formset = ScheduleFormSet(request.POST)

        if schedules_formset.is_valid():
            schedules_formset.save()
            return HttpResponseRedirect(reverse('products:line-schedules-edit',
                                                kwargs={'line_slug': line_slug}))
    else:
        schedules_formset = ScheduleFormSet(queryset=queryset)

    context = {
        'line': line,
        'formset': schedules_formset
    }

    return render(request, 'line-schedules-edit.html', context)


# template
{{ formset.management_form }}
{% csrf_token %}
{% for form in formset.forms %}
  {% for hidden in form.hidden_fields %}{{ hidden }}{% endfor %}
  {% for field in form.visible_fields %}
    {{ field.errors }}
    {{ field }}
  {% endfor %}
{% endfor %}

С этой структурой я постоянно получаю сообщение об ошибке недопустимой даты для срока, когда я использую «3 марта 2018 года», тогда как если я ввожу в браузер форму «2018-03-18», это работает. Тем не менее, в оболочке я могу убедиться, что оба формата даты работают:

In [35]: POST = {
   'form-TOTAL_FORMS': '2',
   'form-INITIAL_FORMS': '0',
   'form-MAX_NUM_FORMS': '2',
   'form-0-name': 'Test',
   'form-0-status': 'Not started',
   'form-0-due_date': '2018-03-20',
   'form-1-name': 'Test',
   'form-1-status': 'Not started',
   'form-1-due_date': 'March 20, 2018'
}

In [36]: qdict = QueryDict('', mutable=True)
         qdict.update(POST)
         formset = ScheduleFormSet(qdict)

In [37]: formset.is_valid()
Out[37]: True

Почему представление и шаблон не проходят проверку и почему в чистом методе формы отсутствует ключ due_date?


person yekta    schedule 20.03.2018    source источник
comment
re: синхронизация данных и метод clean, Form.clean запускается после выполнения проверки определенных полей, и если значение поля считается недействительным в этот момент, оно будет удалено из cleaned_data. Позже в потоке его не будет, когда вы нажмете метод clean. Я не знаю, почему это не проходит проверку.   -  person ryanmrubin    schedule 20.03.2018


Ответы (1)


Оказывается, все, что мне нужно было сделать, это предоставить входные форматы для предварительной обработки формата перед его отправкой в ​​​​модель. Должно быть, произошла ошибка встроенной проверки модели, поскольку она не может сохранить ее в форме «2 марта 2018 года».

Используя input_formats в форме, мы можем привести его к нужному формату до того, как модель его обработает:

class ScheduleForm(forms.ModelForm):

    class Meta:
        model = models.Schedule
        fields = ['name', 'user', 'status', 'due_date']

    due_date = forms.DateField(widget=forms.DateInput(format='%d %B, %Y'),
                               input_formats=('%d %B, %Y',),
                               required=False)
person yekta    schedule 20.03.2018