Django ajax GET and POST request
In this article, you will learn how to post a form data and retrieve it from the model without refreshing the web page using the Django and Ajax.
Ajax is a technique to provide fast and dynamic web services. It updates or retrieves data asynchronously by exchanging data over the server. The XMLHttpRequest object is used to exchange data with a server behind the scenes. This means that it is possible to update parts of a web page, without reloading the whole page.
If you have not installed the Django package, please follow the Django documentation for initial setup.
Here is a simple real time example showing how you might go about implementing a form that works for AJAX GET requests as well as AJAX POST. GET and POST are the only HTTP methods to use when dealing with forms.
We are creating an empty project 'event' and a new app 'participant'-
(env) c:\python37\Scripts\projects>django-admin startproject event
(env) c:\python37\Scripts\projects>cd event
(env) c:\python37\Scripts\projects\event>django-admin startapp participant
settings.py
After creating the app, we need to tell Django we're going to use it. Do this by editing your settings file and changing the INSTALLED_APPS setting to add the name of the module.
INSTALLED_APPS += [
'participant',
]
It is also required to edit the database settings in 'settings.py'-
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'demo',
'USER': 'root',
'PASSWORD': '',
'HOST': 'localhost',
'PORT': '3306'
}
}
models.py
A model is a definitive source of information about your data. Each model maps to a single database table, and each attribute represents a database field. The given model defines a participant, which has first_name, last_name, email, dob, and city as fields.
from django.db import models
# Create your models here.
class Participant(models.Model):
# participant form fields
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
email = models.CharField(max_length = 250)
dob = models.DateField(auto_now=False, auto_now_add=False)
city = models.CharField(max_length=150)
class Meta:
db_table = "participants"
Make Migration and Runserver
Let's run the following command to perform makemigrations and migrate.
(env) c:\python37\Scripts\projects\event>python manage.py makemigrations
(env) c:\python37\Scripts\projects\event>python manage.py migrate
and then run the server using following command -
(env) c:\python37\Scripts\projects\event>python manage.py runserver
forms.py
In a similar way that a model class's fields map to database fields, a form class's fields map to HTML form elements. The ModelForm is required to collect the form data. So, we have created a ModelForm 'forms.py' under 'participant' app, whose fields are taken from the database table. A form field is represented to a user in the browser as an HTML "widget", but these can be overridden as required. Here, we have overridden the dob form field to "Date of birth" and set the year range -
from .models import Participant
from django import forms
import datetime
class ParticipantForm(forms.ModelForm):
## set the label name of the date field.
dob = forms.DateField(
label='Date of birth',
# Set the years range from 1985 to (current year - 15)
widget=forms.SelectDateWidget(years=range(1985, datetime.date.today().year-15))
)
class Meta:
model = Participant
fields = ("__all__")
views.py
Form data sent back to a Django website is processed with a view, and to handle the form, we need to instantiate it in the view for the URL where we want it to be published. In 'views.py', let's import JsonResponse, ParticipantForm form, and Participant model. We have created two views, 'displayData' and 'postParticipant'. The 'displayData' view takes all participants object from database and display in 'index.html' page. The postParticipant view handles the Ajax POST request.The is_ajax returns True if the request was made via an XMLHttpRequest.
from django.shortcuts import render
from django.http import JsonResponse
from django.core import serializers
from .forms import ParticipantForm
from .models import Participant
def displayData(request):
form = ParticipantForm()
participants = Participant.objects.all()
return render(request, "index.html", {"form": form, "participants": participants})
def postParticipant(request):
# request should be ajax and method should be POST.
if request.is_ajax and request.method == "POST":
# get the form data
form = ParticipantForm(request.POST)
# save the data and after fetch the object in instance
if form.is_valid():
instance = form.save()
# serialize in new participant object in json
ser_instance = serializers.serialize('json', [ instance, ])
# send to client side.
return JsonResponse({"instance": ser_instance}, status=200)
else:
# some form errors occured.
return JsonResponse({"error": form.errors}, status=400)
# some error occured
return JsonResponse({"error": ""}, status=400)
# Create your views here.
Create Template Files
main.html
This HTML file include jQuery library and Bootstrap files. We have specified two blocks for content and javascript, which will be included from 'index.html' page.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>{% block title %}{% endblock title %}</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
</head>
<body>
{% block content %}
{% endblock content %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
{% block javascript %}
{% endblock javascript %}
</body>
</html>
index.html
In this file, first we have extended the main.html file. It contains two sections. The first section displays the participant form and second section display the participants data. We have placed the jQuery coding part at the bottom of the page. On click the submit button, the jquery code serializes the form data and make Ajax requests to post the form data.
To provides protection against Cross Site Request Forgeries, you must add the {% csrf_token %} template tag to the form, which adds a hidden input field containing a token that gets sent with each POST request.
{% extends "main.html" %}
{% block content %}
<div class="container">
<form id="participant-form">
{% csrf_token %}
{% for field in form %}
<div class="form-group row">
<label class="col-sm-2 col-form-label">
<strong>{{ field.label }}</strong>
</label>
<div class="col-sm-10">
{{ field }}
</div>
</div>
{% endfor %}
<div class="form-group row">
<input type="submit" class="btn btn-primary" value="Create Participant" />
</div>
<form>
</div>
<div class="container">
<table class="table table-bordered" id="showdata">
<thead>
<tr>
<th scope="col">First Name</th>
<th scope="col">Last Name</th>
<th scope="col">Email</th>
<th scope="col">Birth Date</th>
<th scope="col">City</th>
</tr>
</thead>
<tbody>
{% for parti in participants %}
<tr>
<td>{{parti.first_name}}</td>
<td>{{parti.last_name}}</td>
<td>{{parti.email}}</td>
<td>{{parti.dob | date:"Y-m-d"}}</td>
<td>{{parti.city}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock content %}
{% block javascript %}
<script>
$("#participant-form").submit(function (e) {
// preventing default actions
e.preventDefault();
// serialize the data for sending the form data.
var serializedData = $(this).serialize();
// Ajax Call
$.ajax({
type: 'POST',
url: "{% url 'post_participant' %}",
data: serializedData,
// handle a successful response
success: function (response) {
// On successful, clear all form data
$("#participant-form").trigger('reset');
// Display new participant to table
var instance = JSON.parse(response["instance"]);
var fields = instance[0]["fields"];
$("#showdata tbody").prepend(
`<tr>
<td>${fields["first_name"]||""}</td>
<td>${fields["last_name"]||""}</td>
<td>${fields["email"]||""}</td>
<td>${fields["dob"]||""}</td>
<td>${fields["city"]||""}</td>
</tr>`
)
},
error: function (response) {
// alert non successful response
alert(response["responseJSON"]["error"]);
}
})
})
</script>
{% endblock javascript %}
urls.py
At last, we have added path to route page to the particular link-
from django.contrib import admin
from django.urls import path
from participant.views import (
displayData,
postParticipant,
)
urlpatterns = [
path('', displayData),
path('post/ajax/participant', postParticipant, name = "post_participant"),
]
This is how the above application looks like on the browser -
Related Articles
Get data from MySQL in Django View with ModelsDjango send email on contact form submission
Generate and download a CSV file in Django
Read and write a file using Django
Django Export Model Data to CSV
Django pass variable from view to HTML template
Django Simple File Upload
Django Custom User Model SignUp, Login and Logout
Django ajax GET and POST request
Django Pagination with Ajax and jQuery
Display image from database in Django
How to upload image and add in Django model Imagefield
Python program to convert Celsius to Fahrenheit
Python send mail to multiple recipients using SMTP server
How to generate QR Code in Python using PyQRCode
Python programs to check Palindrome strings and numbers
CRUD operations in Python using MYSQL Connector
Fibonacci Series Program in Python
Python File Handler - Create, Read, Write, Access, Lock File
Python convert XML to JSON
Python convert xml to dict
Python convert dict to xml