Returning form errors for AJAX request in Django Returning form errors for AJAX request in Django ajax ajax

Returning form errors for AJAX request in Django


This question is old, but I think the shortest answer might be using simple json in a view like this.

from django.utils import simplejsondef 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)

now you can access the data in your jquery like Calvin described above. Jquery makes it easy to handle the data, You could do something like this:

var errors = jQuery.parseJSON(data)    alert(errors.username)


Wow, it's been a year since I've seen this thread. Well, with the advent of Django 1.3 and the magical, undocumented class-based views, it's become more easy to extent Django's view related functionality. My project which makes heavy use of Django's class-based generic CRUS views need AJAX and JSON functionality. I've added an example of how I've modified Django's update view to support AJAX and return AJAX responses in the JSON format. Have a look:

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            )

The response JSON contains three fields — message (which is a human readable message), data (which is this case would be the list of form errors) and success (which is either true or false, indicating whether the request was successful or not respectively.). This is very easy to handle in jQuery client-side. A sample response looks like:

Content-Type: application/json{"message": "Validation failed.", "data": {"host": ["This field is required."]}, "success": false}

This is just an example of how I serialized the form errors to JSON and implemented it in a class-based generic view but can be cannibalized to work with regular style views as well.


When I use front-end validation, usually the response contains chunks that you can access through dot notation (dataReturned.specificData).

Based on what and how you are returning data is the key to how to access it. The more modular you handle the data returned, the easier it is to access.

// 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 }});