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>
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')
<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>
$ python manage.py runserver
- {% 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?
from django.http import JsonResponse
#Usage in view
return JsonResponse({"foo":"bar"})
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.






Great post!
This is a great post. I’m actually amazed there isn’t a component out there that does this and only this. I’m probably going to wrap this up into a (tiny) library and put on github.
You can use anything from here, if it helps you.
Hi! I followed your short tutorial, and most things worked except for the final data transfer, and I don’t get our programmed alert message. The debugging dev tools in Chrome report “Uncaught ReferenceError: $ is not defined” on this line of your code: (for me it’s line 24 & 25)
//When submit is clicked
$(“#submit”).click(function(e) {
Any suggestions? Meanwhile I will troubleshoot this further.
Please check whether you have included Jquery file in HTML. Error says that you don’t have jquery loaded. So try to include https://code.jquery.com/ jquery.min.js and retry again.
Thanks for replying. Oops I found the problem. It was simply that I pasted the jQuery stuff at the top before the declaration of #submit. Kind of silly, but anyway I pasted all the jQuery towards the bottom (where it should go anyway) and it behaves as expected.
Very helpful post! Thank you.
good post
Amazing post!!!! I was looking for this tutorial since such a long time! Rest of the tutorials on internet are just too complicated! Thanks again!
Worked perfectly! This is maybe the 5th tutorial I’ve read and the one that finally made sense!
Quick note, I don’t know if it’s my display or what but from what I can tell your view has some syntax errors:
Says:
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
should be:
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
Well, my indentaiton got erased but you get the idea. Missing endquotes and end parenthesis on get.
Seriously, thanks. I’ve spent 2 or 3 days trying to figure this out (I’m new to ajax, bad at js) but trying your example, then rewriting my form following your example, got it working in about 30 minutes. You’re awesome.
Thanks. You can request any confusing part in Django and I will try to write on it. 🙂 narenarya@live.com
Easier and practical explanation. Very useful in 2017