Wednesday, August 28, 2013

Django & Ajax - Disable Django's Cross-Site-Request_Forgery protection on a view

This is an example about how to make an ajax call from a django template without applying the cross-site-request-forgery mechanism of Django, using @csrf_exempt annotation.

1. Views

from apps.testajax import models
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.views.decorators.csrf import ensure_csrf_cookie, csrf_exempt
from django.http import HttpResponse
import json


def home(request):
my_models = models.MyModel.objects.all()
return render_to_response('home.html', locals(), context_instance=RequestContext(request))


@csrf_exempt
def del_model(request):
msg = 'Fail'
if request.is_ajax():
if 'models_to_del' in request.POST.keys() and request.POST['models_to_del']:
models_to_del_pks = request.POST['models_to_del'].split(',')
if '' in models_to_del_pks:
models_to_del_pks.remove('')
models.MyModel.objects.filter(pk__in=models_to_del_pks).delete()
msg = 'Models were deleted'
else:
msg = 'This is not an ajax request'

jsondata = json.dumps(msg)
return HttpResponse(jsondata, mimetype='application/json')


2. Template


Here is the script that call an ajax request to delete the selected models:
...

<script>
...
         var r=confirm("Are you sure to delete these selected Models?");
if (r==true) {
var url = '/del_model/';
$.ajax({
url: url,
cache: false,
type: 'POST',
data: { 'models_to_del': selected_models },
success: function(data) {
console.log(data);
$.ajax({
url: "",
context: document.body,
success: function(s, x) {
$(this).html(s);
}
});
}
});
}
...
</script>





Remember: put the url pattern mapping of the ajax view function in the root urlconf (ajax/urls.py). If you put the url pattern for the del_model ajax view in a sub urls.py file, it will not work, the cross-site-request-forgery protection mechanism of Django will prevent the ajax view call.


Download example source code: https://www.dropbox.com/s/tgtn4p18kgm6h97/ajax.tar.gz

Reference: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/