#jquery #django #validation #dialog
#jquery #django #проверка #диалоговое окно
Вопрос:
У меня есть форма Django, которую я динамически загружаю в диалоговое окно jQuery после того, как пользователь нажал на ссылку на веб-странице. Ссылка href в ссылке указывает на страницу Django, которая содержит только содержимое формы, а не весь макет сайта.
$('#add-note').click(функция() { $('#dialog').load($(this).attr('href')).диалоговое окно ({ заголовок: 'Добавить заметку', модальный: true, перетаскиваемый: false, Минимальная ширина: 500, }); возвращает false; });
Это работает нормально, если пользователь отправляет форму, которая проверяется в серверной части. Однако, если форма содержит ошибки проверки, Django перенаправляет браузер обратно на страницу формы, которая в данном случае на самом деле не является страницей, которую пользователь просматривал в данный момент.
Видите ли, пользователь был на совершенно другой странице, и форма была просто динамически загружена в диалоговое окно jQuery. Итак, вопрос в том, какой был бы наилучший способ справиться с подобной ситуацией? Как мне открыть форму с ошибками проверки обратно в диалоговом окне, а не на самой странице формы?
Вся помощь высоко ценится!
Ответ №1:
При использовании AJAX и Django forms я обычно делаю это следующим образом (хотя примеров кода нет, но я думаю, вы поймете идею).
- создайте другой шаблон только для рендеринга этой формы (без блоков, без расширения из другого шаблона)
- на ваш взгляд, который отображает шаблон для отображения формы, отобразите эту форму напрямую в html через
django.template.loader.render_to_string
(используя шаблон, который я упомянул). Поместите эту отображаемую форму в контекст, поместив ее в шаблон. - В вашем шаблоне создайте контейнер для формы и отобразите html внутри него.
- когда вы теперь отправляете свою форму через AJAX, убедитесь, что обработчик, который отправляет форму, также отображает форму (как в вашем исходном представлении через
django.template.loader.render_to_string
) и возвращает по крайней мере это как html. Thls будет включать ошибки, если форма была недействительной. - При получении ответа AJAX просто полностью замените форму в вашем контейнере. После этого вы получили форму Django, содержащую все ошибки из исходной отправки формы django.
Преимущества этого подхода заключаются в том, что Django по-прежнему заботится о проверке формы и отображении ошибок, и вам не нужно заботиться об этом через Javascript (может немного раздражать, особенно из-за ошибок в полях). Недостатком, конечно, является то, что вам приходится писать для нее больше внутреннего кода. 🙂
Комментарии:
1. Спасибо за эти инструкции! Я сделал примерно так, как вы предложили. В качестве небольшого отличия я возвращаю объект данных JSON из представления, чтобы я мог передать URL-адрес перенаправления в представление, если данные действительны. Это был самый простой способ, которым я мог сделать перенаправление после успешной публикации.
2. @Torsten очень хорошее решение для борьбы за интеграцию проверки формы, управляемой ajax, с django!
Ответ №2:
Если форма недопустима, я возвращаю ошибку вместе с сообщением вместо возврата 200, успеха и т.д. В представлении это выглядит примерно так:
if form.is_valid():
...hooray!
else:
return HttpResponse(json.dumps({'error': msg}), status=400,
mimetype='application/json')
В ajax-запросе, который я только что сделал, запрос завершится ошибкой, и я где-нибудь покажу ошибку пользователю (обычно в диалоговом окне), и javascript будет выглядеть примерно так:
$.ajax({
type: 'POST',
data: form,
error: function(data) {
var error = $.parseJSON(data.responseText);
$('#error').text(error.error);
$('#error').show();
}
});
Ответ №3:
Быстрое и грязное решение, отличное от ajax, было бы:
$(function() {
{% if form.errors %}
$( "#form" ).dialog( "open" );
{% endif %}
});
Или если у вас есть formset:
{% if formset.is_bound and not formset.is_valid %}
$( "#formset" ).dialog( "open" );
{% endif %}
Примечание: formset.errors всегда будет иметь значение true (это список пустых словарей, если ошибок нет), поэтому вам нужно использовать is_bound и is_valid таким образом, иначе вы всегда будете открывать диалоговое окно после отправки formset.
Редактировать: на самом деле это не совсем отвечает на первоначальный вопрос. Я проследил, чтобы ваша форма была загружена с другого URL. Мое решение работает, если вы обрабатываете форму в том же представлении и просто отображаете ее в диалоговом окне jQuery на той же странице.