У меня большой опыт веб-разработки, не относящейся к Django, но я изо всех сил пытаюсь найти хорошую практику для обработки того, что делать, когда пользователь вводит недопустимые данные в их форме, и я хочу повторно отобразить форму сих представленные данные и формы ошибок также отображаются.У меня есть простая форма с тремя полями, и вот как я наконец-то заставил ее работать.
def get(self, request) :
# Check if we have been redirected...
redirect_html = request.session.pop('form_error_html', False)
if redirect_html : return HttpResponse(redirect_html)
old_data = {'title': 'SakaiCar', 'mileage' : 42,
'purchase_date': '2018-08-14' }
form = BasicForm(initial=old_data)
ctx = {'form' : form}
return render(request, 'form.html', ctx)
def post(self, request) :
form = BasicForm(request.POST)
if not form.is_valid() :
ctx = {'form' : form}
html = render_to_string('form.html', ctx, request=request)
request.session['form_error_html'] = html
return redirect(request.path)
# Do something with the valid data..
return redirect('/')
Мой шаблон действительно простой (мне нравится эта простота):
<p>
<form action="" method="post">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<input type="submit" value="Submit">
</form>
</p>
Теперь этоэтот подход меня немного раздражает, потому что я посылаю всю визуализированную HTML-страницу через сеанс от post()
до get()
.Но я не могу отправить form
с ошибками на месте через сеанс обратно в get()
(это было бы лучше), потому что он не будет сериализован - вы получите "Объект типа 'BasicForm' не JSONсериализации».
Я сделал это другим способом: я извлекаю ошибки из объекта form
в list
, а затем передаю свой собственный список ошибок из post()
в перенаправленный get()
, а затемизмените form.html
для отображения ошибок.
{% if errors %}
{% for error in errors %}
<p style="color:red">Error in {{ error.label }}: {{ error.message }}</p>
{% endfor %}
{% endif %}
Я не включил весь код Python для этой работы - но вы поняли идею.Это выглядит более элегантно, потому что я не помещаю в сеанс каплю HTML, но тогда ошибки отображаются не так, как обычные формы Django.А если бы я использовал хрустящие формы - тогда все эти хрустящие качества пользовательского интерфейса не вступили бы в игру.
Я даже думал о том, чтобы вытащить ошибки в коде post()
и передать их в get()
черезсеанса и затем вставьте их в объект form
в get()
до render()
- это тоже будет выглядеть более элегантно.Если мне станет скучно, я мог бы попытаться покопаться в структуре форм и реализовать это.
Я просто не могу поверить, что с Джанго так много удивительной встроенной магии - что я не могу просто сказать что-то вродеreturn form.post_redirect_get()
в коде not form.is_valid
.
Я хочу что-то, что представляет собой реплицируемый шаблон, который легко объяснить и максимально использовать элементы пользовательского интерфейса Django.