当后端表单验证失败时,如何在 jQuery 对话框中重新打开 Django 表单?

发布于 2024-11-07 03:40:36 字数 607 浏览 1 评论 0原文

我有一个 Django 表单,在用户单击网页上的链接后,我将其动态加载到 jQuery 对话框中。链接中的 href 指向仅包含表单内容的 Django 页面,而不包含整个站点布局。

        $('#add-note').click(function() {
            $('#dialog').load($(this).attr('href')).dialog({
                title: 'Add a note',
                modal: true,
                draggable: false,
                minWidth: 500,
            });

            return false;
        });

如果用户提交在后端验证的表单,则效果很好。但是,如果表单包含验证错误,Django 会将浏览器转发回表单页面,在这种情况下,该页面实际上并不是用户当前正在查看的页面。

看,用户位于完全不同的页面上,表单只是动态加载到 jQuery 对话框中。那么问题来了,处理这种情况的最佳方法是什么?如何打开带有验证错误的表单返回到对话框而不是表单页面本身?

非常感谢所有帮助!

I have a Django form which I load dynamically to a jQuery dialog after a user has clicked a link on a webpage. The href in the link points to a Django page that contains just the form contents, not the whole site layout.

        $('#add-note').click(function() {
            $('#dialog').load($(this).attr('href')).dialog({
                title: 'Add a note',
                modal: true,
                draggable: false,
                minWidth: 500,
            });

            return false;
        });

This works fine if the user submits a form that validates in the backend. However, if the form contains validation errors, Django forwards the browser back to the form page, which in this case is not actually the page the user was viewing at the moment.

See, the user was on a totally different page and the form was just dynamically loaded to the jQuery dialog. So the question is, what would be the best way to handle this kind of situation? How do I open the form with validation errors back in to the dialog and not the form page itself?

All help appreciated greatly!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤独陪着我 2024-11-14 03:40:36

当使用 AJAX 和 Django 表单时,我通常采用以下方法(虽然没有代码示例,但我想您会明白的)。

  • 创建一个不同的模板,仅用于在您的视图中呈现此表单(无块,无从另一个模板扩展),
  • 该模板呈现模板以显示表单,通过 django.template.loader.render_to_string 将此表单直接呈现为 html代码>(使用我提到的模板)。将这个呈现的表单放入上下文中,将其推送到模板。
  • 在模板中为表单创建一个容器并在其中呈现 html。
  • 当您现在通过 AJAX 提交表单时,请确保提交表单的处理程序也呈现该表单(就像通过 django.template.loader.render_to_string 在您的原始视图中一样)并至少将其返回为 html 。如果表单无效,这将包括错误。
  • 获取 AJAX 响应时,只需完全替换容器中的表单即可。之后,您将获得 Django 表单,其中包含原始 Django 表单提交中的所有错误。

这种方法的优点是 Django 仍然负责表单验证和错误显示,并且您不需要通过 Javascript 来处理它(可能有点烦人,特别是对于字段错误)。缺点当然是你必须为它编写更多的后端代码。 :)

When using AJAX and Django forms I usually do it the following approach (no code examples though, but I think you will get the idea).

  • create a different template just for rendering this form (no blocks, no extending from another template)
  • in your view which render the template to display the form, render this form direclty into html via django.template.loader.render_to_string (using the template I mentioned). Put this rendered form into the context pushing it to the template.
  • In your template create a container for the form and render the html inside there.
  • when you now submit your form via AJAX make sure the handler which submit the form renders the form as well (like in your original view via django.template.loader.render_to_string) and returns at least this as html. Thls will include the errors if the form was not valid.
  • When getting the AJAX response simply replace the form in your container completely. After that you got the Django form including all the errors from a original django form submit.

The advantages of this approach are that Django is still taking care of the form validation and error displaying and you don't need to take care of it via Javascript (can be a little annoying especially for field errors). Disadvantage is of course that you have to write more backend code for it. :)

小巷里的女流氓 2024-11-14 03:40:36

如果表单无效,我会返回一个错误和一条消息,而不是返回 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();
  }
}); 

If a form isn't valid, I return an error along with a message instead of returning 200, success, etc. In the view it's something like this:

if form.is_valid():
    ...hooray!
else:
    return HttpResponse(json.dumps({'error': msg}), status=400, 
                        mimetype='application/json')

In the ajax request I just made the the request will fail, and I'll display the error to the user somewhere (usually in the dialog) and the javascript will look something like this:

$.ajax({
  type: 'POST',
  data: form,
  error: function(data) {
    var error = $.parseJSON(data.responseText);
    $('#error').text(error.error);
    $('#error').show();
  }
}); 
山田美奈子 2024-11-14 03:40:36

一个快速而肮脏的非ajax解决方案是:

$(function() {
    {% if form.errors %}
        $( "#form" ).dialog( "open" );
    {% endif %}
});

或者如果你有一个表单集:

{% if formset.is_bound and not formset.is_valid %}
    $( "#formset" ).dialog( "open" );
{% endif %}

注意:formset.errors将始终为true(如果没有任何错误,它是一个空字典列表),所以你必须使用is_bound和is_valid 以这种方式,否则您将始终在提交表单集后打开该对话框。

编辑:
这实际上并不能完全回答最初的问题。我发现您的表单是从不同的网址加载的。如果您在同一视图中处理表单并且只是将其显示在同一页面上的 jQuery 对话框中,我的解决方案确实有效。

A quick and dirty, non-ajax solution would be:

$(function() {
    {% if form.errors %}
        $( "#form" ).dialog( "open" );
    {% endif %}
});

Or if you have a formset:

{% if formset.is_bound and not formset.is_valid %}
    $( "#formset" ).dialog( "open" );
{% endif %}

Note: formset.errors will always be true (it's a list of empty dictionaries if there aren't any errors) so you have to use is_bound and is_valid in this way or you'll always open the dialog after submitting the formset.

Edit:
This doesn't actually quite answer the original question. I oversaw that your form was loaded from a different url. My solution does work if you're handling the form in the same view and you're simply displaying it in a jQuery dialog on that same page.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文