Intro

We all know that Django is a powerful framework. Many of us deals with posting data from a HTML form to a Django view and process it. You should have never cared of Ajax way of posting the data. Some of you tried AJAX but faced few painful intros to setup a perfectly running Django-Ajax implementation. So,I came up this time to tell you how to do that.After this tutorial you will feel quite comfortable about implementing ajax posts and also will keep this article as a reference for future. Source code for upcoming tutorial available at following link.

What is AJAX?

Simply put AJAX is about updating parts of a web page, without reloading the whole page.

Suppose we need to update any parts of our website page ,then we must use Ajax. For posting data back to server ajax is required. Now why we should use it with Django ?. I believe following things will answer you.

Using Ajax, we can craft data format that sent back to server.

We can handle the situations like successful post or failure or error.

Drop all burden on client rather than server wherever it is possible.

For implementing progress bars ajax post is the best way.

Drop messages framework to display something ,I hate it. Use JSON response returned from Ajax post to wake up cool notification models etc.

If you didn’t understand the above points , cool. I too didn’t once. The simple thing I am gonna show is , how to post something back to server from HTML and collect acknowledgement that returned back.

Let us begin the show

We are going to see the demonstration from scratch. Let us create a Django project for that. Remember we am playing with Django >= 1.7 here.

$ pip install Django==1.7.3

This installs Django1.7 on your system.

$ django-admin startproject ajaxpost #Now create an app called mainapp inside ajaxpost $ django-admin startapp mainapp

Then the directory structure will be in this way.

Now let us add the superuser to begin with. Default db will be SQilte3. First do a migration for django to create default user tables in db. So do this.

$ python manage.py migrate

Now create a super user for admin.

$ python manage.py createsuperuser

That’s it. Now we are going to create a home page which has the email field and a password for collecting user data. It is to show data passage from ( client -> server ,server -> client) . Simple,but extremely useful in 100 use-cases.

After creation of superuser ,just create a view for our home page. ajaxpost/urls.py looks like below

#ajaxpost/urls.py from django.contrib import admin from mainapp import views urlpatterns = patterns('', url(r'^admin/', include(admin.site.urls)), url(r'^',views.home , name=u'home') )

Now modify the views of mainapp to the following.

from django.shortcuts import render from django.http import JsonResponse def home(request): return JsonResponse({"hello":"pythonist"})

Now just save and do a runserver. Next Go to http://localhost:8000 and you will find this thing.

$ python manage.py runserver

See how simple it is to send a Json response from a Django1.7 view. Now we are going to crete a HTML file for our home page and try to take data from it to create user. For that create a folder called templates in your project root and make a file called base.html. tree structure of our project looks this.

Ok. Now I am adding template directories location to settings.py. Add this line to ajaxpost/settings.py

TEMPLATE_DIRS = ( BASE_DIR + '/templates/', )

Now Django can find template files. So add this HTML content to templates/base.html

<html> <head> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"> <link href="http://getbootstrap.com/examples/signin/signin.css" rel="stylesheet"> </head> <body> <div class="container"> <form class="form-signin" method="POST"> {% csrf_token %} <h2 class="form-signin-heading">Enter Details</h2> <label for="inputEmail" class="sr-only">Email address</label> <input type="email" id="inputEmail" class="form-control" placeholder="Email address" required autofocus> <label for="inputPassword" class="sr-only">Password</label> <input type="password" id="inputPassword" class="form-control" placeholder="Password" required> <button id="submit" class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button> </form> </div> <script src="http://code.jquery.com/jquery-2.1.4.min.js"></script> </body> </html>

When you fire runserver and go to http://localhost:8000 , you will find a nice bootstrap Enter details form like this.

I hope things are clear. Follow from the top , if you are in doubt.

Now comes the Ajax part

Instead of doing a normal submit , let us have an Ajax post block in our HTML file. Django relies on csrf token for the validity of data posted to the server. So in addition to data , we should send csrf-token. In default django submission,it is automatically sent. But in case of Ajax , we need to take care of that.

Take the below JS code as Granted and place it in a new <script></script> tag in base.html

<script> //For getting CSRF token function getCookie(name) { var cookieValue = null; if (document.cookie && document.cookie != '') { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = jQuery.trim(cookies[i]); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) == (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } //For doing AJAX post //When submit is clicked $("#submit").click(function(e) { //Prevent default submit. Must for Ajax post.Beginner's pit. e.preventDefault(); //Prepare csrf token var csrftoken = getCookie('csrftoken'); //Collect data from fields var email = $('#inputEmail').val(); var password = $('#inputPassword').val(); //This is the Ajax post.Observe carefully. It is nothing but details of where_to_post,what_to_post //Send data $.ajax({ url : window.location.href, // the endpoint,commonly same url type : "POST", // http method data : { csrfmiddlewaretoken : csrftoken, email : email, password : password }, // data sent with the post request // handle a successful response success : function(json) { console.log(json); // another sanity check //On success show the data posted to server as a message alert('Hi '+json['email'] +'!.' + ' You have entered password:'+ json['password']); }, // handle a non-successful response error : function(xhr,errmsg,err) { console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console } }); }); </script>

Now Don’t forget to place {% csrf_token %} next to the form tag in base.html. Let us modify the mainapp/views.py.

from django.shortcuts import render from django.http import JsonResponse def home(request): if request.method == 'POST': #POST goes here . is_ajax is must to capture ajax requests. Beginner's pit. if request.is_ajax(): #Always use get on request.POST. Correct way of querying a QueryDict. email = request.POST.get('email') password = request.POST.get('password') data = {"email":email , "password" : password} #Returning same data back to browser.It is not possible with Normal submit return JsonResponse(data) #Get goes here return render(request,'base.html')

Now everything for demonstration is built. We need to wrap up things and do a runserver. Before that complete templates/base.html file looks this way.

<html> <head> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"> <link href="http://getbootstrap.com/examples/signin/signin.css" rel="stylesheet"> </head> <body> <div class="container"> <form class="form-signin" method="POST"> {% csrf_token %} <h2 class="form-signin-heading">Enter Details</h2> <label for="inputEmail" class="sr-only">Email address</label> <input type="email" id="inputEmail" class="form-control" placeholder="Email address" required autofocus> <label for="inputPassword" class="sr-only">Password</label> <input type="password" id="inputPassword" class="form-control" placeholder="Password" required> <button id="submit" class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button> </form> </div> <script src="http://code.jquery.com/jquery-2.1.4.min.js"></script> <script> //For getting CSRF token function getCookie(name) { var cookieValue = null; if (document.cookie && document.cookie != '') { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = jQuery.trim(cookies[i]); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) == (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } //For doing AJAX post $("#submit").click(function(e) { e.preventDefault(); var csrftoken = getCookie('csrftoken'); var email = $('#inputEmail').val(); var password = $('#inputPassword').val(); //This is the Ajax post.Observe carefully. It is nothing but details of where_to_post,what_to_post $.ajax({ url : window.location.href, // the endpoint,commonly same url type : "POST", // http method data : { csrfmiddlewaretoken : csrftoken, email : email, password : password }, // data sent with the post request // handle a successful response success : function(json) { console.log(json); // another sanity check //On success show the data posted to server as a message alert('Hi '+json['email'] +'!.' + ' You have entered password:'+ json['password']); }, // handle a non-successful response error : function(xhr,errmsg,err) { console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console } }); }); </script> </body> </html>

Ok. Now fire up the server using

$ python manage.py runserver

Now I went to http://localhost:8000 and entered these details.

email : pikachu@pokemon

password: charizard

When I click sign in this is what I got.

Hurray. We got it. Data is passed from client to server using Ajax and then server sent same data to client as JSON to display alert message.

This is how we pass information to the server using Ajax . Ajax is mainly used for long polling. Long polling is process in which, Ajax sends request from client to server asking the latest information.Then it updates the contents of HTML with data obtained. Here, we stressed four things. In case of failure of any one, Ajax post may not work.Those things are listed below.

{% csrf_token %} just below form tag.

csrfmiddlewaretoken in Ajax POST data.

is_ajax() handler in Django view.

get(‘parameter’) method on request.POST

What is new in Django 1.7?

In Django 1.7 ,we have JsonResponse which directly encodes a Python dictionary to JSON object without dumping data .

from django.http import JsonResponse #Usage in view return JsonResponse({"foo":"bar"})

Before you used to do this like

import json return HttpResponse(json.dumps({"foo":"bar"}), content_type="applciation/json")

Conclusion I hope you got something from this tutorial. I faced problems when I started doing Ajax posts a year back. All tutorials on web misses one or more important things , so things won’t work. That gives us great frustration. I here showed a simple, working example of Ajax post in Django. Use it. source code is available at this link.