Как повторно открыть форму Django в диалоговом окне jQuery при сбое проверки формы в серверной части?

#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 на той же странице.