Tech Incent
Django

How to work with django ajax requests ?

django ajax request

You saw in the web application. Clicking a button, data save/load in content without reloading pages. That’s ajax. Ajax stands for Asynconic Javascript XMLHttpRequest. The purpose of using ajax makes save and load data without loading the entire page.

So there are many scenarios where are you use ajax in the Django application. Ajax makes the data load faster and simply post data.
So in this tutorial, we learn jquery ajax for the Django application to register the new users but it can be used in other form submissions or request JSON data. We follow this line…

Create a registration Form

Make and edit forms.py file for registration form

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from django import forms
from django.contrib.auth.models import User
class UserRegistrationForm(forms.ModelForm):
password1 = forms.CharField(
label='Password',
widget=forms.PasswordInput(attrs={'placeholder': 'Password'})
)
password2 = forms.CharField(
label='Password confirmation',
widget=forms.PasswordInput(attrs={'placeholder': 'Re-Enter Password'})
)
class Meta:
model = User
fields = ['first_name', 'last_name', 'email', 'username']
def save(self, commit=True):
# Save the provided password in hashed format
user = super(UserRegistrationForm, self).save(commit=False)
password = self.cleaned_data["password1"]
user.set_password(password)
if commit:
user.save()
return user
from django import forms from django.contrib.auth.models import User class UserRegistrationForm(forms.ModelForm): password1 = forms.CharField( label='Password', widget=forms.PasswordInput(attrs={'placeholder': 'Password'}) ) password2 = forms.CharField( label='Password confirmation', widget=forms.PasswordInput(attrs={'placeholder': 'Re-Enter Password'}) ) class Meta: model = User fields = ['first_name', 'last_name', 'email', 'username'] def save(self, commit=True): # Save the provided password in hashed format user = super(UserRegistrationForm, self).save(commit=False) password = self.cleaned_data["password1"] user.set_password(password) if commit: user.save() return user
from django import forms
from django.contrib.auth.models import User

class UserRegistrationForm(forms.ModelForm):
    password1 = forms.CharField(
        label='Password',
        widget=forms.PasswordInput(attrs={'placeholder': 'Password'})
    )
    password2 = forms.CharField(
        label='Password confirmation',
        widget=forms.PasswordInput(attrs={'placeholder': 'Re-Enter Password'})
    )
    class Meta:
        model = User
        fields = ['first_name', 'last_name', 'email', 'username']
    
    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super(UserRegistrationForm, self).save(commit=False)
        password = self.cleaned_data["password1"]
        user.set_password(password)
        if commit:
            user.save()
        return user

Create register views

Edit views.py file

Function Base View

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from django.shortcuts import render, redirect, reverse
from django.http.response import JsonResponse
from .forms import UserRegistrationForm
def registration_form_view(request):
form = UserRegistrationForm(request.POST or None)
if request.method == 'POST':
if form.is_valid():
form.save()
if request.is_ajax():
return JsonResponse({'success': True}, status=201)
return redirect(reverse('home'))
else:
if request.is_ajax():
return JsonResponse({'success': False, 'errors': form.errors}, status=406)
return render(request, 'register_form.html', {'form': form})
from django.shortcuts import render, redirect, reverse from django.http.response import JsonResponse from .forms import UserRegistrationForm def registration_form_view(request): form = UserRegistrationForm(request.POST or None) if request.method == 'POST': if form.is_valid(): form.save() if request.is_ajax(): return JsonResponse({'success': True}, status=201) return redirect(reverse('home')) else: if request.is_ajax(): return JsonResponse({'success': False, 'errors': form.errors}, status=406) return render(request, 'register_form.html', {'form': form})
from django.shortcuts import render, redirect, reverse
from django.http.response import JsonResponse

from .forms import UserRegistrationForm

def registration_form_view(request):
    form = UserRegistrationForm(request.POST or None)

    if request.method == 'POST':
        if form.is_valid():
            form.save()
            if request.is_ajax():
                return JsonResponse({'success': True}, status=201)
            return redirect(reverse('home'))
        else:
            if request.is_ajax():
                return JsonResponse({'success': False, 'errors': form.errors}, status=406)
    return render(request, 'register_form.html', {'form': form})

Class Base View

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from django.shortcuts import render, redirect, reverse
from django.http.response import JsonResponse
from django.views.generic import CreateView
from .forms import UserRegistrationForm
class RegistrationClassBaseView(CreateView):
""" class Base register view, handle with ajax or none ajax"""
template_name = 'register_form.html'
form_class = UserRegistrationForm
def form_valid(self, form):
instance = form.save(commit=False)
# other staff
instance.save()
if request.is_ajax():
return JsonResponse({'success': True}, status=201)
return redirect(reverse('home'))
def form_invalid(self, form):
if self.request.is_ajax():
return JsonResponse({'success': False, 'errors': form.errors}, status=400)
return super().form_invalid(form)
from django.shortcuts import render, redirect, reverse from django.http.response import JsonResponse from django.views.generic import CreateView from .forms import UserRegistrationForm class RegistrationClassBaseView(CreateView): """ class Base register view, handle with ajax or none ajax""" template_name = 'register_form.html' form_class = UserRegistrationForm def form_valid(self, form): instance = form.save(commit=False) # other staff instance.save() if request.is_ajax(): return JsonResponse({'success': True}, status=201) return redirect(reverse('home')) def form_invalid(self, form): if self.request.is_ajax(): return JsonResponse({'success': False, 'errors': form.errors}, status=400) return super().form_invalid(form)
from django.shortcuts import render, redirect, reverse
from django.http.response import JsonResponse
from django.views.generic import CreateView

from .forms import UserRegistrationForm

class RegistrationClassBaseView(CreateView):
    """ class Base register view, handle with ajax or none ajax"""
    template_name = 'register_form.html'
    form_class = UserRegistrationForm

    def form_valid(self, form):
        instance = form.save(commit=False)
        # other staff
        instance.save()
        if request.is_ajax():
            return JsonResponse({'success': True}, status=201)
        return redirect(reverse('home'))

    def form_invalid(self, form):
        if self.request.is_ajax():
            return JsonResponse({'success': False, 'errors': form.errors}, status=400)
        return super().form_invalid(form)

This view work on both nono ajax, and ajax request

Add this registration views to the router

Add urls.py and edit it with …

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from django.urls import path
from .views import registration_form_view, RegistrationClassBaseView
urlpatterns = [
path('signup', registration_form_view, name='register_view')
path('signup-classbase', RegistrationClassBaseView.as_view(), name='class_base_register_view')
]
from django.urls import path from .views import registration_form_view, RegistrationClassBaseView urlpatterns = [ path('signup', registration_form_view, name='register_view') path('signup-classbase', RegistrationClassBaseView.as_view(), name='class_base_register_view') ]
from django.urls import path

from .views import registration_form_view, RegistrationClassBaseView


urlpatterns = [
    path('signup', registration_form_view, name='register_view')
    path('signup-classbase', RegistrationClassBaseView.as_view(), name='class_base_register_view')
]

Setup base.html templates

Initial Template base template file with base.py

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- optional Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<title>Hello, world!</title>
{% block css %}
{% endblock %}
</head>
<body>
{% block content %}
{% endblock %}
<!-- jQuery is medetory for Ajax request -->
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<!-- Optional bootstrap and popper -->
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
{% block js %}
{% endblock %}
</body>
</html>
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- optional Bootstrap CSS --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous"> <title>Hello, world!</title> {% block css %} {% endblock %} </head> <body> {% block content %} {% endblock %} <!-- jQuery is medetory for Ajax request --> <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script> <!-- Optional bootstrap and popper --> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script> {% block js %} {% endblock %} </body> </html>
<!doctype html>
<html lang="en">
  <head>    
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- optional Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
    <title>Hello, world!</title>
    {% block css %}
    {% endblock %}
  </head>
  <body>
    {% block content %}
    {% endblock %}
    <!-- jQuery is medetory for Ajax request -->
    <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
    <!-- Optional bootstrap and popper -->
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
    {% block js %}
    {% endblock %}
</body>
</html>

Jquery file is mandatory for jquery ajax requests. we are using bootstrap but it’s optional for $.ajax.

So I declare “{% block js %}”. it helps to render javascript code on every page. Learn more about extends templates

Create register_form.html templates and ajax code in the template

What is going on register_form.html file?

Explain: First of all I extend the base.html file. than declare form in Block Content. then we add Javascript AJAX jquery code in Block js. This ajax requires Jquery. Make sure you $.ajax code render under jquery file.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{% extends 'base.html' %}
{% block content %}
<div class="container mt-5">
<form id="signup_form" action="{% url 'register_view' %}" method="post">
{% csrf_token %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger" role="alert"> {{ error }}</div>
{% endfor %}
{{ form.as_p }}
<button>Submit</button>
</form>
</div>
{% endblock %}
{% block js %}
<script>
(function($) {
let signUpForm = $('#signup_form');
signUpForm.on('submit', function(e) {
e.preventDefault();
let $this = $(this);
let method = $this.attr('method');
let endpoint = $(this).attr('action');
let data = $this.serialize();
$.ajax({
method: method,
url: endpoint,
data: data,
success: function(resonse) {
console.log(resonse)
if (resonse.success){
signUpForm[0].reset()
alert('succesfully registered')
} else{
alert('data not valid registered')
}
},
error: function({responseText}) {
console.log(responseText)
alert('form data not vaild')
}
})
})
}(jQuery));
</script>
{% endblock %}
{% extends 'base.html' %} {% block content %} <div class="container mt-5"> <form id="signup_form" action="{% url 'register_view' %}" method="post"> {% csrf_token %} {% for error in form.non_field_errors %} <div class="alert alert-danger" role="alert"> {{ error }}</div> {% endfor %} {{ form.as_p }} <button>Submit</button> </form> </div> {% endblock %} {% block js %} <script> (function($) { let signUpForm = $('#signup_form'); signUpForm.on('submit', function(e) { e.preventDefault(); let $this = $(this); let method = $this.attr('method'); let endpoint = $(this).attr('action'); let data = $this.serialize(); $.ajax({ method: method, url: endpoint, data: data, success: function(resonse) { console.log(resonse) if (resonse.success){ signUpForm[0].reset() alert('succesfully registered') } else{ alert('data not valid registered') } }, error: function({responseText}) { console.log(responseText) alert('form data not vaild') } }) }) }(jQuery)); </script> {% endblock %}
{% extends 'base.html' %}

{% block content %}
<div class="container mt-5">
    <form id="signup_form" action="{% url 'register_view' %}" method="post">
        {% csrf_token %}
        {% for error in form.non_field_errors %}
        <div class="alert alert-danger" role="alert"> {{ error }}</div>
        {% endfor %}
        {{ form.as_p }}
        <button>Submit</button>
    </form>
</div>
{% endblock %}

{% block js %}
<script>
    (function($) {
        let signUpForm = $('#signup_form');
        signUpForm.on('submit', function(e) {
            e.preventDefault();
            let $this = $(this);
            let method = $this.attr('method');
            let endpoint = $(this).attr('action');
            let data = $this.serialize();
            $.ajax({
                method: method,
                url: endpoint,
                data: data,
                success: function(resonse) {
                    console.log(resonse)
                    if (resonse.success){
                        signUpForm[0].reset()
                        alert('succesfully registered')
                    } else{
                        alert('data not valid registered')
                    }
                },
                error: function({responseText}) {
                    console.log(responseText)
                    alert('form data not vaild')
                }
            })
        })
    }(jQuery));
</script>
{% endblock %}

Browse application and test ajax

function base and class view output same

01. browse function base view http://127.0.0.1:8000/signup

02. browse class base view  http://127.0.0.1:8000/signup-classbase

03. Make an invalid form ajax submission

ajax-error
Invalid form ajax submit

04. Make a valid form ajax submission

ajax-success
Valid form ajax submit

Ajax get request

01. create an API user view

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from django.core import serializers
from django.http.response import JsonResponse
from django.contrib.auth import get_user_model
def user_list_view(request):
""" get json data """
users = serializers.serialize(
'json',
get_user_model().objects.all(),
fields=('first_name','last_name', 'username', 'email')
)
return JsonResponse({'users': users}, status=200)
from django.core import serializers from django.http.response import JsonResponse from django.contrib.auth import get_user_model def user_list_view(request): """ get json data """ users = serializers.serialize( 'json', get_user_model().objects.all(), fields=('first_name','last_name', 'username', 'email') ) return JsonResponse({'users': users}, status=200)
from django.core import serializers
from django.http.response import JsonResponse
from django.contrib.auth import get_user_model
def user_list_view(request):
    """ get json data """
    users = serializers.serialize(
        'json', 
        get_user_model().objects.all(), 
        fields=('first_name','last_name', 'username', 'email')
    )
    return JsonResponse({'users': users}, status=200)

02. Add routing user_list_view form

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from django.urls import path
from .views import registration_form_view, RegistrationClassBaseView, user_list_view
urlpatterns = [
path('signup', registration_form_view, name='register_view'),
path('signup-classbase', RegistrationClassBaseView.as_view(), name='class_base_register_view'),
path('ajax/users', user_list_view, name='json_user_list')
from django.urls import path from .views import registration_form_view, RegistrationClassBaseView, user_list_view urlpatterns = [ path('signup', registration_form_view, name='register_view'), path('signup-classbase', RegistrationClassBaseView.as_view(), name='class_base_register_view'), path('ajax/users', user_list_view, name='json_user_list')
from django.urls import path
from .views import registration_form_view, RegistrationClassBaseView, user_list_view
urlpatterns = [
    path('signup', registration_form_view, name='register_view'),
    path('signup-classbase', RegistrationClassBaseView.as_view(), name='class_base_register_view'),
    path('ajax/users', user_list_view, name='json_user_list')

03. Test APIBrowse http://127.0.0.1:8000/ajax/users

04. Make Ajax request

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$.ajax({
method: 'get',
url: "{% url 'json_user_list' %}",
success: function({users}) {
console.log(users)
},
error: function(err){
console.log(err)
}
})
$.ajax({ method: 'get', url: "{% url 'json_user_list' %}", success: function({users}) { console.log(users) }, error: function(err){ console.log(err) } })
$.ajax({
    method: 'get',
    url: "{% url 'json_user_list' %}",
    success: function({users}) {
        console.log(users)
    },
    error: function(err){
        console.log(err)
    }
})

Checkout tutorial source code

https://github.com/techincent/django-snippets

Related posts

How to create Django form?

Sajal Mia

How to create a virtual environment for Django?

Sajal Mia

How to optimize your Django application for more speed with ORM?

Sajal Mia

How to delete file when models instance is delete or update in Django?

Sajal Mia

Understanding Django and django design principles

Tech Incent

Explained Django inline formset factory with example?

Sajal Mia