Contact Information

KodeBlog

We're Available 24/ 7. Drop us an email.

Django Ajax

AJAX allows us to create interactive applications that update only certain sections of the web page without reloading the whole page. AJAX standards for Asynchronous JavaScript & XML. In a nutshell, we use JavaScript in the background asynchronously to interact with a backend API that returns data and we use JavaScript to update the DOM.

Topics to be covered

We will cover the following topics in this lesson

  • jQuery Library
  • jQuery UI
  • Books Search Simple JSON API
  • Books Search Autocomplete using jQuery
  • Summary

jQuery Library

jQuery is a lightweight library that allows us to perform complex JavaScript operations using minimal code. You don't need to know jQuery inside out to complete this lesson successfully but if you know the Basics of JavaScript then that is an added advantage.

We will modify our base template to load jQuery from a CDN Network.

Open the file templates/base.html and at the bottom add the following script to load jQuery.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

jQuery UI

jQuery UI is a User Interface library that is built on top of jQuery library. It consisist of GUI widgets that use JavaScript and CSS. Just like jQuery, it allows us to do more while writing less code. We will modify our base template again to include the CSS and JavaScript files from a CDN network.

Open the file templates/base.html and at the bottom add the following script to load jQuery UI CSS and JavaScript.

In the head section, add the following CSS

<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">

Now at the bottom of the page where the JavaScript code is located, add the following just below the script that loads jQuery.

<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>

The complete update base.html file should now be as follows

{% load static %}
<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <meta name="description" content="">
        <meta name="author" content="">
        <title>{{title}}</title>
        <link rel="shortcut icon" href="{% static "images/favicon.png" %}">
        <!-- Bootstrap core CSS -->
        <link href="{% static "vendor/bootstrap/css/bootstrap.min.css" %}" rel="stylesheet">
        <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
        <link href="{% static "css/style.css" %}" rel="stylesheet">
    </head>
    <body>
        <!-- Navigation -->
        <nav class="navbar navbar-expand-lg navbar-dark bg-dark static-top">
            <div class="container">
                <a class="navbar-brand" href="{% url 'home' %}">KODEBLOG Bookstore</a>
                <button class="navbar-toggler" type="button"
                    data-toggle="collapse" data-target="#navbarResponsive"
                    aria-controls="navbarResponsive" aria-expanded="false"
                    aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse" id="navbarResponsive">
                    <ul class="navbar-nav ml-auto">
                        <li class="nav-item active">
                            <a class="nav-link" href="{% url 'home' %}">Home
                                <span class="sr-only">(current)</span>
                            </a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="{% url 'books.index' %}">Books</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="{% url 'authors.index' %}">Authors</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="{% url 'categories.index' %}">Categories</a>
                        </li>
                        {% if user.is_authenticated %}
                        <li class="nav-item">
                            <a class="nav-link" href="{% url 'books.create' %}">Add Book</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="{% url 'authors.create' %}">Add Author</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="{% url 'categories.create' %}">Add Category</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="{% url 'logout' %}">Log out</a>
                        </li>
                        {%else%}
                        <li class="nav-item">
                            <a class="nav-link" href="{% url 'login' %}">Log in</a>
                        </li>
                        {% endif %}

                    </ul>
                </div>
            </div>
        </nav>
        <!-- Page Content -->
        <div class="container">
            {% block content %}{% endblock %}
        </div>
        <!-- Bootstrap core JavaScript -->
        <script src="{% static "vendor/jquery/jquery.slim.min.js" %}"></script>
        <script src="{% static "vendor/bootstrap/js/bootstrap.bundle.min.js" %}"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
        {% block scripts %}{% endblock %}
    </body>
</html>

Books Search Simple JSON API

We want to create requests using Ajax in our application.

Let's create a search bar on the homepage which searches for the books by title and gives the results as clickable suggestions.

Scenario:

Every time the text in the search-bar is updated, we send a request as ajax to get books which title is like the text. If there is a book, we will get their titles and pk as a suggestion. If we click on a suggestion, we will be redirected to the details page of that book.

Opens the views.py file in the books application and define the following function

from django.http import JsonResponse


def search(request):
    data  = request.GET

    if data:
        search_query = data.get('title')
        
        query = Book.objects.filter(title__icontains = search_query).extra(
            select = {
                'label':'title',
                'value': 'id'
            }
        ).values('label', 'value')
        
        result = list(query)

        return JsonResponse(result, safe=False)

HERE,

  • from django.http import JsonResponse imports the JsonResponse object from Django
  • def search(request): defines our simple API function
  • data = request.GET data is the content of our GET request. So our view works with GET request only. If we have the title keyword in our search, its value (e.g. work) will be the variable to search in the database.
  • if data: uses the if statement to check if the variable data contains something
  • search_query = data.get('title') extracts the value of title from the variable data
  • query = Book.objects.filter(...) We will have a new query_set using the filter. let's look at each part of the query: filter (): filters the results. It is like WHERE clause. icontains: checks if the title is Like the string we have searched for. It is case-insensitive. extra(select={'label':'title','value': 'id' } ) We want to have some changes in our query result. In our Ajax response, we need two variables: label and value. In our query_set we have title and id. we can change them in the extra method. values('label', 'value'): Instead of looking at all the columns (select * ...), we just look for the column we need.
  • result = list(query) The query variable is a queryset object. However, we need to have a response in JSON. So, we convert our queryset result to a list
  • return JsonResponse(result, safe=False) returns a JSON response.

Update urls.py in books application to include the following

path('books/search', search, name = 'books.search'),

Open the web browser and enter the following URL

[
    {
        "label": "Clean Code",
        "value": 1
    },
    {
        "label": "Clean Agile: Back to Basics",
        "value": 6
    },
    {
        "label": "Clean Architecture: A Craftsman's Guide to Software Structure",
        "value": 8
    }
]

The above is the response that our AJAX request will be getting back from our simple API.

Books Search Autocomplete using jQuery

Open the file index.html located in the templates directory and update the code as follows

{% extends "base.html" %}
{% block content %}
<div class="row search-bar">
    <form class="form" method="get">
        <div class="form-group col-md-12">
            <input type="text" id="title" class="form-control search-title"
                name="title" placeholder="Enter the title of book" autocomplete="off">
        </div>
    </form>
</div>
{% endblock %}
{% block scripts %}
<script type="text/javascript">
    $('#title').keyup(
    function(){
        var txt = $('#title').val();

        $.get("/books/search", {title: "" + txt },
            function(data){
                $('#title').autocomplete({
                source: data,
                select: function( event, ui ) {
                    var url = "/books/"+ $.trim(ui.item.value);
                    event.preventDefault();
                    window.location.href = url;
                }
                });
            }
        );
      }
    );
  </script>
{% endblock %}

HERE,

  • <form class="form" method="get">...</form> defines a form that users will use to search for book titles.
  • {% block scripts %}...{% endblock %} defines a block that contains JavaScript code that is specific to this page only.
  • $('#title').keyup( defines an event keyup for the input with the id of title. When the text in it is changed, a function is called. This function gets the text in the input field and sends an AJAX request to the server. The request is in GET method and the search text will be in URL as a parameter. for example, if we type is clean our URL will be: http://127.0.0.1:8000/books/search?title=clean. After getting a response a new function is called. This function, calls the autocomplete function of jQuery UI and puts a suggestion on our search-bar with the data it has got. Each suggestion is a link to its book.

Now, after we search for a book title, a new ajax request is sent to the server and Django runs a query to find the books that their title matches the keywords. Then it returns the title and id of the books, as an ajax response. Then jQuery UI shows them as a suggestion.

Django AJAX

Summary

Ajax allows us to create interactive web applications that only update the necessary part of section of the page with reloading. jQuery is a JavaScript library that simplifies writing JavaScript code by doing the heavy lifting for us in the background. jQuery UI is another library built on jQuery that provides interactive GUI components such as Autocomplete in a text box. Django allows us to return database results as a JSON object for simple APIs that should be consumed by AJAX requests.

Author: Rodrick Kazembe

Rodrick is a developer who works on Desktop, Web and Mobile Applications. He is familiar with Python, Java, JavaScript, C++, C#, Kotlin, PHP, Python and the list goes on. Rodrick enjoys sharing knowledge especially when it comes to technology.

Django Form Processing

Leave A Reply