在 Django 中返回 AJAX 请求的表单错误
Posted
技术标签:
【中文标题】在 Django 中返回 AJAX 请求的表单错误【英文标题】:Returning form errors for AJAX request in Django 【发布时间】:2011-02-07 03:51:29 【问题描述】:我一直在寻找有关 Django 和 jQuery 的方法。我在 Django 中构建了一个基本表单。单击提交时,我使用 jQuery 向服务器发出 AJAX 请求以发布我的数据。这一点似乎工作正常,我已经设法保存数据。当表单无效时,Django 返回一个 ValidationError。谁能告诉我如何返回这组错误消息作为对我的 AJAX 请求的响应,以便我可以轻松地使用 JS 遍历它并执行任何操作?
我找到了thissn-p。查看 JS 位 (processJson),您会发现他似乎通过从响应 html 中提取错误消息来获取错误消息。这对我来说似乎有点笨拙。这是最好的方法吗?
对于任何含糊之处,我深表歉意。
提前致谢。
【问题讨论】:
【参考方案1】:这个问题很老,但我认为最短的答案可能是在这样的视图中使用简单的 json。
from django.utils import simplejson
def ajax(request):
if request.method == 'POST':
form = someForm(request.POST)
if form.is_valid():
form.save()
return HttpResponse(something)
else:
errors = form.errors
return HttpResponse(simplejson.dumps(errors))
else:
return HttpResponse(something)
现在您可以像上面描述的 Calvin 一样访问您的 jquery 中的数据。 Jquery 可以轻松处理数据,您可以这样做:
var errors = jQuery.parseJSON(data)
alert(errors.username)
【讨论】:
这行得通。谢谢震动。我的印象是您必须执行“form.errors.as_ul()”或等效项的 json 转储......但这更好。干杯。jQuery.parseJSON(data)
时数据中的第 1 行第 t 列有语法错误。我的数据以Object readyState: 4, getResponseHeader: .aj...
开头【参考方案2】:
哇,我已经一年没看到这个帖子了。好吧,随着 Django 1.3 和神奇的、未记录的基于类的视图的出现,扩展 Django 的视图相关功能变得更加容易。我的项目大量使用了 Django 基于类的通用 CRUS 视图,需要 AJAX 和 JSON 功能。我添加了一个示例,说明如何修改 Django 的更新视图以支持 AJAX 并以 JSON 格式返回 AJAX 响应。看看:
def errors_to_json(errors):
"""
Convert a Form error list to JSON::
"""
return dict(
(k, map(unicode, v))
for (k,v) in errors.iteritems()
)
class HybridUpdateView(UpdateView):
"""
Custom update generic view that speaks JSON
"""
def form_valid(self, form, *args, **kwargs):
"""
The Form is valid
"""
form.save()
self.message = _("Validation passed. Form Saved.")
self.data = None
self.success = True
payload = 'success': self.success, 'message': self.message, 'data':self.data
if self.request.is_ajax():
return HttpResponse(json.dumps(payload),
content_type='application/json',
)
else:
return super(HybridUpdateView, self).form_valid(
form, *args, **kwargs
)
def form_invalid(self, form, *args, **kwargs):
"""
The Form is invalid
"""
#form.save()
self.message = _("Validation failed.")
self.data = errors_to_json(form.errors)
self.success = False
payload = 'success': self.success, 'message': self.message, 'data':self.data
if self.request.is_ajax():
return HttpResponse(json.dumps(payload),
content_type='application/json',
)
else:
return super(HybridUpdateView, self).form_invalid(
form, *args, **kwargs
)
响应 JSON 包含三个字段 — message
(这是人类可读的消息)、data
(在这种情况下将是表单错误列表)和 success
(即 true
或false
,分别表示请求是否成功。)。这在 jQuery 客户端很容易处理。示例响应如下所示:
Content-Type: application/json
"message": "Validation failed.", "data": "host": ["This field is required."], "success": false
这只是我如何将表单错误序列化为 JSON 并在基于类的通用视图中实现它的示例,但也可以将其与常规样式视图一起使用。
【讨论】:
【参考方案3】:当我使用前端验证时,通常响应包含可以通过点符号 (dataReturned.specificData) 访问的块。
基于您返回数据的内容和方式是如何访问数据的关键。您处理返回的数据越模块化,就越容易访问。
// Start ajax request to server
$.ajax(
url: '/path_to_service',
type: 'POST',
data: key: value ,
// Do something with the data
success: function(data)
// Data is everything that is returned from the post
alert(data);
// data.message could be a piece of the entire return
alert(data.message);
error: function(data) // Handle fatal errors
);
【讨论】:
嗨 Calvin,什么是错误,什么是成功?我应该返回一些价值吗?在服务器端,我如何以 JSON 格式返回验证错误列表,以便我可以使用错误函数在客户端列出它们?这是让我感到困惑的一点。谢谢。 成功是您发送服务的内容发回数据。成功时,您将在其中操作数据并对其进行处理(通常更新字段或显示消息)。错误是服务返回致命错误(服务已损坏或某些内容已损坏)。通常你会返回 false 并且什么都不做,但如果你的东西需要服务存在,你会告诉用户服务已经关闭。 JSON 方面的事情由您的后端服务处理。不幸的是,我的后端技能还不够,所以我不能告诉你如何编写服务。【参考方案4】:您可以使用我的 adjax 库为您处理这个问题。将应用安装在路径上的某处,链接adjax.js
文件并将以下内容添加到您的视图中:
import adjax
@adjax.adjax_response
def my_view(request):
# prepare my_form with posted data as normal
adjax.form(request, my_form)
加载adjax.js
文件后使用javascript启用表单:
$('form').adjaxify();
然后享受:-)
更多功能在这里:http://adjax.hardysoftware.com.au/how/。我将在下周发布“1.0”版本,让我知道进展如何。谷歌代码项目在这里:http://code.google.com/p/django-adjax/
【讨论】:
【参考方案5】:我知道这是一个古老且已回答的问题!还是愿意贡献的。我最喜欢的解决方案是对应该错误 json 的方法使用装饰器。
import traceback,sys,simplejson
def unhandled(e):
"""
Helper function to format an exception and it's stack
"""
exc_type, exc_value, exc_traceback = sys.exc_info()
lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
stack = ''.join(line for line in lines)
return HttpResponse(simplejson.dumps("error":-1, "response": e.message ,"stack":stack), content_type='application/json')
def use_json_except(f):
def new_f(*args):
try:
return f(*args)
except Exception as e:
return unhandled(e)
return new_f
然后你定义你的 Django 方法:
@use_json_except
def add_annotation(request):
....
装饰器将捕获任何未捕获的异常并输出带有错误信息和堆栈的 json。
我个人觉得对于混合 html 和 json 响应的 django 服务器来说,这是一个非常好的解决方案。
【讨论】:
以上是关于在 Django 中返回 AJAX 请求的表单错误的主要内容,如果未能解决你的问题,请参考以下文章
如何清除以前的 AJAX 响应数据(不是 html/表单数据)? - Django/AJAX
Django 1.9 AJAX 表单 CSRF 令牌 403 错误 - “未设置 CSRF cookie”