How to reopen a Django form in a jQuery dialog when the form validation fails in the backend?
我有一个 Django 表单,在用户单击网页上的链接后,我将其动态加载到 jQuery 对话框中。链接中的 href 指向一个 Django 页面,该页面仅包含表单内容,而不是整个站点布局。
1 2 3 4 5 6 7 8 9 10 | $('#add-note').click(function() { $('#dialog').load($(this).attr('href')).dialog({ title: 'Add a note', modal: true, draggable: false, minWidth: 500, }); return false; }); |
如果用户提交在后端进行验证的表单,这会正常工作。但是,如果表单包含验证错误,Django 会将浏览器转发回表单页面,在这种情况下,该页面实际上并不是用户当前正在查看的页面。
看,用户在一个完全不同的页面上,表单只是动态加载到 jQuery 对话框中。所以问题是,处理这种情况的最佳方法是什么?如何将带有验证错误的表单打开回对话框而不是表单页面本身?
非常感谢所有帮助!
当使用 AJAX 和 Django 表单时,我通常采用以下方法(虽然没有代码示例,但我想你会明白的)。
- 创建一个不同的模板来呈现这个表单(没有块,没有从另一个模板扩展)
-
在呈现模板以显示表单的视图中,通过
django.template.loader.render_to_string (使用我提到的模板)将此表单直接呈现为 html。将此呈现的表单放入上下文中,将其推送到模板。 - 在您的模板中,为表单创建一个容器并在其中呈现 html。
-
当您现在通过 AJAX 提交表单时,请确保提交表单的处理程序也呈现表单(就像在您通过
django.template.loader.render_to_string 的原始视图中一样)并至少将其作为 html 返回。如果表单无效,thls 将包含错误。 - 获得 AJAX 响应时,只需完全替换容器中的表单即可。之后,您将获得包含原始 django 表单提交的所有错误的 Django 表单。
这种方法的优点是 Django 仍在处理表单验证和错误显示,您不需要通过 Javascript 处理它(可能有点烦人,尤其是字段错误)。缺点当然是你必须为它编写更多的后端代码。 :)
如果表单无效,我会返回一个错误以及一条消息,而不是返回 200、success 等。在视图中,它是这样的:
1 2 3 4 5 | if form.is_valid(): ...hooray! else: return HttpResponse(json.dumps({'error': msg}), status=400, mimetype='application/json') |
在我刚刚发出的 ajax 请求中,请求将失败,我将在某处(通常在对话框中)向用户显示错误,并且 javascript 将如下所示:
1 2 3 4 5 6 7 8 9 | $.ajax({ type: 'POST', data: form, error: function(data) { var error = $.parseJSON(data.responseText); $('#error').text(error.error); $('#error').show(); } }); |
一个快速而肮脏的非 ajax 解决方案是:
1 2 3 4 5 | $(function() { {% if form.errors %} $("#form" ).dialog("open" ); {% endif %} }); |
或者如果你有一个表单集:
1 2 3 | {% if formset.is_bound and not formset.is_valid %} $("#formset" ).dialog("open" ); {% endif %} |
注意:formset.errors 将始终为真(如果没有任何错误,它是一个空字典列表),因此您必须以这种方式使用 is_bound 和 is_valid,否则您将始终在提交表单集后打开对话框.
编辑:
这实际上并不能完全回答原始问题。我看到您的表单是从不同的 url 加载的。如果您在同一视图中处理表单并且您只是在同一页面上的 jQuery 对话框中显示它,我的解决方案确实有效。