Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Django 2 Ajax CRUD with Python 3.7 and jQuery

5.00/5 (1 vote)
15 Dec 2019CPOL3 min read 5.5K  
How to send Ajax requests in Django 2 and Python 3.7 to add CRUD operations in your application and manipulate your Django models and database without having to refresh your web pages each time

In this tutorial, you’ll learn how to send Ajax requests in Django 2 and Python 3.7 to add CRUD operations in your application and manipulate your Django models and database without having to refresh your web pages each time.

Ajax stands for Asynchronous JavaScript and XML and it’s a way for getting data from the server and updating the page on the fly without refreshing the page.

Creating a Virtual Environment

Make sure you have Python 3 installed (Python 3.7 is the latest as of this writing) and start by creating a virtual environment for your project’s packages:

JavaScript
$ python -m venv myenv

Next, activate your virtual environment using:

JavaScript
$ source myenv/bin/activate

Installing Django 2 and Creating a Project

Now, you need to install Django using pip:

JavaScript
$ python -m pip install django

Next, create a Django project using:

JavaScript
$ django-admin startproject djangoajaxdemo

Next, you need to create a Django application using the manage.py script:

JavaScript
$ cd djangoajaxdemo
$ python manage.py startapp rooms

Next, you need to add it to your project’s installed apps array in the settings.py file:

JavaScript
INSTALLED_APPS = [
	'django.contrib.admin',
	'django.contrib.auth',
	'django.contrib.contenttypes',
	'django.contrib.sessions',
	'django.contrib.messages',
	'django.contrib.staticfiles',
	'rooms'
]

Adding jQuery

In this tutorial, we’ll be using jQuery to send Ajax requests to Django. You can also use any other HTTP client like Axios, the JavaScript Fetch API available on modern browsers or the XMLHttpRequest interface.

First of all, you need to get jquery from the official website and include it in your project or use a CDN. Go to the official website and get the CDN of the version of jQuery you want to use.

In my case, I’ll be using jQuery 3.3.1 from https://code.jquery.com/jquery-3.3.1.min.js.

Inside the rooms application, create a templates/rooms folder and create a base.html file:

JavaScript
{% load static %}
<!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">
<title> Django Ajax CRUD with jQuery</title>
<link  rel="stylesheet"  
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
crossorigin="anonymous">
</head>
  <body>
    <div class="container d-flex h-100">
      <div class="row justify-content-center">
        <div class="col-10">
          {% block main %}
          {% endblock %}
        </div>
      </div>
    </div>
{% block js %}
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
{% endblock %}
{% block extrajs %}
{% endblock %}
  </body>
</html>

Adding a Model

We’ll be adding CRUD operations against a Room model. Open the rooms/models.py file and add the following code:

JavaScript
from django.db import models

class  Room(models.Model):
	ROOM_TYPES = (
		(1, 'Single'),
		(2, 'Double'),
		(3, 'Triple'),
	)
	
	name = models.CharField(max_length=50)
	status = models.CharField(max_length=30, blank=True)
	room_number = models.IntegerField(blank=True, null=True)
	nobeds = models.IntegerField(blank=True, null=True)
	room_type = models.PositiveSmallIntegerField(choices=ROOM_TYPES)

Adding CRUD Views

In the rooms/views.py file, add the following class based and generic views for performing CRUD operations:

JavaScript
from django.views.generic import View
from django.http import JsonResponse
from django import forms
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.forms.models import model_to_dict
from .models import Room

class  RoomForm(forms.ModelForm):
	class  Meta:
		model = Room
		fields =  '__all__'

class  RoomList(View):
	def  get(self, request):
		rooms =  list(Room.objects.all().values())
		data =  dict()
		data['rooms'] = rooms
		return JsonResponse(data)

class  RoomDetail(View):
	def  get(self, request, pk):
		room = get_object_or_404(Room, pk=pk)
		data =  dict()
		data['room'] = model_to_dict(room)
		return JsonResponse(data)

@method_decorator(csrf_exempt, name='dispatch')
class  RoomCreate(CreateView):
	def  post(self, request):
		data =  dict()
		form = RoomForm(request.POST)
		if form.is_valid():
			room = form.save()
			data['room'] = model_to_dict(room)
		else:
			data['error'] =  "form not valid!"
		return JsonResponse(data)

class  RoomUpdate(View):
	def  post(self, request, pk):
		data =  dict()
		room = Room.objects.get(pk=pk)
		form = RoomForm(instance=room, data=request.POST)
		if form.is_valid():
			room = form.save()
			data['room'] = model_to_dict(room)
		else:
			data['error'] =  "form not valid!"
		return JsonResponse(data)

class  RoomDelete(View):
	def  post(self, request, pk):
		data =  dict()
		room = Room.objects.get(pk=pk)
		if room:
			room.delete()
			data['message'] =  "Room deleted!"
		else:
			data['message'] =  "Error!"
		return JsonResponse(data)

Next, let’s add the URLs. Open the urls.py file and add:

JavaScript
from django.urls import path, include
from django.views.generic.base import TemplateView
from rooms import views

urlpatterns = [
	path('rooms/', TemplateView.as_view(template_name="rooms/main.html"), name='room_main'),
	path('rooms/list', views.RoomList.as_view(), name='room_list'),
	path('rooms/create', views.RoomCreate.as_view(), name='room_create'),
	path('rooms/update/<int:pk>', views.RoomUpdate.as_view(), name='room_update'),
	path('rooms/delete/<int:pk>', views.RoomDelete.as_view(), name='room_delete'),
	path('rooms/<int:pk>', views.RoomDetail.as_view(), name='room_detail'),	
]

Adding a Template

Since we’ll be using Ajax for making CRUD operations in our Django application, we will not need multiple pages or templates but instead we’ll conceive our application as a Single Page Application.

Let’s create a main.html file inside the rooms/templates/rooms folder with the following content:

HTML
{% extends 'rooms/base.html' %}
{% block main %}  
{% endblock %}

{% block extrajs %}
&lt;script  src="{% static 'js/app.js' %}"&gt;&lt;/script&gt;
{% endblock %}

Next under your project’s root folder, create the static/js/ folder and add an app.js file with the following content:

JavaScript
$(function () {
	console.log("Hello!");
});

In your urls.py file, add the following URL pattern so you can access your static files in development mode:

JavaScript
from django.conf import settings
# [...]

if settings.DEBUG:
	from django.contrib.staticfiles.urls import staticfiles_urlpatterns
	urlpatterns += staticfiles_urlpatterns()

In the settings.py file, add the following setting to configure your static folder:

JavaScript
STATICFILES_DIRS = (
	os.path.join(BASE_DIR, 'static'),
)

If your run your application and visit the http://127.0.0.1:8000/rooms/, you should see a Hello! in the console of your browser which means your static files are configured correctly.

In this tutorial, we’ll implement the list and delete operations. For create and update operations, we’ll see them in the next tutorial.

Getting Rooms with jQuery.ajax()

In your app.js file, add the following code to get data from the rooms/list endpoint by sending a GET Ajax request:

JavaScript
$.ajax({
    url:  '/rooms/list',
    type:  'get',
    dataType:  'json',
    success: function  (data) {
        let rows =  '';
        data.rooms.forEach(room =&gt; {
        rows += `
        &lt;tr&gt;
            &lt;td&gt;${room.room_number}&lt;/td&gt;
            &lt;td&gt;${room.name}&lt;/td&gt;
            &lt;td&gt;${room.nobeds}&lt;/td&gt;
            &lt;td&gt;${room.room_type}&lt;/td&gt;
            &lt;td&gt;
                &lt;button class="btn deleteBtn" data-id="${room.id}"&gt;Delete&lt;/button&gt;
                &lt;button class="btn updateBtn" data-id="${room.id}"&gt;Update&lt;/button&gt;
            &lt;/td&gt;
        &lt;/tr&gt;`;
    });
    $('[#myTable](https://paper.dropbox.com/?q=%23myTable) &gt; tbody').append(rows);
    $('.deleteBtn').each((i, elm) =&gt; {
        $(elm).on("click",  (e) =&gt; {
            deleteRoom($(elm))
        })
    })
    }
});

Deleting Rooms with jQuery.ajax()

Next, you need to add an implementation for the deleteRoom(e) method:

JavaScript
function  deleteRoom(el){
	roomId  =  $(el).data('id')
	$.ajax({
		url:  `/rooms/delete/${roomId}`,
		type:  'post',
		dataType:  'json',
		success:  function (data) {
			$(el).parents()[1].remove()
		}
	});
}

Now go back to your rooms/templates/rooms/main.html template and add the table:

HTML
{% block main %}
<table  class="table table-bordered"  id="myTable">
<thead>
<th>
Room Number
</th>
<th>
Name
</th>
<th>
Number of Beds
</th>
<th>
Type
</th>
<th>
Actions
</th>
</thead>
<tbody>
</tbody>
</table>

<div  id="roomform">
	<button  id="createRoom"  class="btn"> Create Room </button>
</div>

{% endblock %}

This is a screenshot of our page at this point:

Django Ajax and jQuery

In the next tutorial, we’ll see how to create a form and send it with jQuery and Ajax to our Django endpoints to create and update rooms.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)