атрибут novalidate form приводит к тому, что данные опускаются - PullRequest
0 голосов
/ 15 ноября 2018

HTML5 позволяет проверять определенные элементы формы на стороне браузера;например, для <input type="number"> появится небольшой пузырь, если вы введете что-либо, кроме цифр.
Эта проверка перед отправкой формы может быть подавлена ​​путем добавления атрибута novalidate к тегу формы или formnovalidate присваивается кнопкам отправки, что делает сервер ответственным за всю проверку.
По умолчанию django использует novalidate, так как ошибки формы гораздо лучше видны.

Но здесь есть одна загвоздка: при использовании novalidate данные любого элемента формы, который может быть проверен на стороне клиента и содержит недопустимые данные, будут опущены взапрос, который достигает сервера.Сервер больше не может проверять данные для этих неисправных элементов, и в результате пользователь, который поместил неверные данные, никогда не узнает о своей ошибке.

forms.py

class WorstFormEver(Form):
    a = IntegerField(required = False) # use the default NumberInput widget, allowing HTML5 validation
    b = IntegerField(required = False, widget = TextInput) # TextInput does not include HTML5 validation

Возьмите эту форму и заполните оба поля буквами.

views.py

class WorstViewEver(FormView):
    form_class = WorstFormEver
    template_name = 'admin/worst.html'
    success_url = reverse_lazy('worst')
    novalidate = True

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['novalidate'] = self.novalidate
        return context

    def post(self, request, *args, **kwargs):
        print(self.request.POST.get('a','PANIC!')) # prints [''] if self.novalidate is True
        return super().post(request, *args, **kwargs)

Можно ожидать, что представление вернет ответ с формой с ошибками в обоих полях, но оно показывает только ошибку дляполе b пока a равно пусто !Неверные данные a никогда не поступали на сервер.

Форма с novalidate - request.POST содержит 'a': [''], 'b': ['bar']: Form with novalidate

Форма без novalidate - форма не может быть опубликована в случае ошибок: Form without novalidate

шаблон

{% extends 'admin/base_site.html' %}

{% block content %}
<form method="post" {% if novalidate %}novalidate{% endif %}>
    {% csrf_token %}
    {{ form }}
    <input type="submit">
</form>
{% endblock content %}

Удаление novalidate даже не позволило бы отправить форму (как и ожидалось).
Я также мог бы заменить все виджеты, которые могли бы поддерживать проверку HTML5, на скучные старые TextInput виджеты, но это скорее похоже на лечение симптомачем причина.

Я бы предпочел не использовать проверку HTML5, так как некоторые формы могут быть довольно большими, а представление ошибок в django намного более ясным (и информативным).

У меня вопрос, как я могу использовать novalidate (потому что я хочу использовать как виджеты, специфичные для поля, так и только проверку django) без потери данных.Проблема в том, что что-то все еще выполняет некоторую проверку и удаление данных, несмотря на явную установку novalidate.

Использование: django v1.11, приведенный выше пример, протестированный с Firefox

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