在Django中返回AJAX请求的表单错误

时间:2010-04-12 19:23:55

标签: jquery ajax django django-forms

我一直在寻找Django和jQuery的方法。我在Django中构建了一个基本表单。在单击提交时,我正在使用jQuery向服务器发出AJAX请求以发布我的数据。这一点似乎工作正常,我已设法保存数据。当表单无效时,Django返回ValidationError。任何人都可以告诉我如何返回这组错误消息作为对我的AJAX请求的响应,这样我就可以轻松地使用JS迭代它并做任何事情吗?

我找到了this代码段。查看JS位(processJson),您会看到他似乎通过从响应HTML中提取错误消息来获取错误消息。这对我来说似乎有些愚蠢。这是最好的方式吗?

我对任何含糊不清道歉。

提前致谢。

5 个答案:

答案 0 :(得分:11)

这个问题很老,但我认为最简单的答案可能是在这样的视图中使用简单的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)

答案 1 :(得分:4)

哇,自从我看过这个帖子已经有一年了。好吧,随着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(其中是truefalse,分别表示请求是否成功。)。这在jQuery客户端非常容易处理。示例响应如下:

Content-Type: application/json

{"message": "Validation failed.", "data": {"host": ["This field is required."]}, "success": false}

这只是我如何将表单错误序列化为JSON并在基于类的通用视图中实现它的一个示例,但也可以同时使用常规样式视图。

答案 2 :(得分:1)

当我使用前端验证时,通常响应包含可以通过点表示法访问的块(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 }
});

答案 3 :(得分:0)

您可以使用我的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”版本,让我知道情况如何。 Google代码项目位于:http://code.google.com/p/django-adjax/

答案 4 :(得分:0)

我知道这是一个陈旧且回答的问题!仍想贡献。我最喜欢的解决方案是使用装饰器来解决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服务器的一个非常好的解决方案。