Introduction
In this article, We are going to build a complete CRUD application with Django by using the most powerful feature CBV (Class Based View). This approach is very efficient for code reusability and allows us to build the Django app in a much faster way.So, without any delay, let’s start. We will create a simple application to manage the student’s information. If you desire, to access the complete code then you can access it from my GitHub repository here. Or keep reading and follow the step-by-step instruction below.
I am using an Ubuntu terminal, so some commands here might need to be adapted to your preferred terminal, especially if you are using Power Shell, Windows Command Prompt, or an Ubuntu Terminal.
Part 1: Setting up the Project
- Create your project folder and move it inside. My folder name is DjangoCrudApp
mkdir DjangoCrudApp cd DjangoCrudApp
2. Create a new virtual environment with venv (mine is called .myenv)
python -m venv .myenv
3. Now we need to activate our virtual environment from the below command.
source .myenv/Scripts/activate
4. Install the Python important packages for the Project.
1. pip install djangorestframework 2. pip install Django==4.0.2 3. pip install django-extensions==3.1.5
Verify the latest version of the above extensions.
5. Start a new Django project. Mine is just called classbasedcrud.
django-admin startproject classbasedcrud .
6. Start a Django app called api.
python manage.py startapp api
7. Open classbasedcrud/settings.py and add rest_framework and the api app to the INSTALLED_APPS list. Don’t change the other lines.
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'api', ]
8. Apply the migrations to create the tables in the sqlite3 database.
python manage.py migrate
9. Create a superuser by running the following command.
python manage.py createsuperuser
Inform a username, email, and password. You will use this data to login into the admin area later.
10. Run the server with python manage.py runserver, visit http://localhost:8000, and check if the app is working correctly.
11. Go to http://localhost:8000/admin, use your login data, and check if you can access the admin area.
Part 2: Define the Models
1. In api/models.py, enter the following code.
from django.db import models # Create your models here. class Student(models.Model): name = models.CharField(max_length=100) roll = models.IntegerField() city = models.CharField(max_length=100)
We are creating a model class (Student), with (name, roll number “roll”, city). In the future, you can create many other classes and relationships between those classes.
Part 3: Create a new category using the admin area
1. Run the commands to create the new tables in the database.
python manage.py makemigrations python manage.py migrate
2 . Open api/admin.py and write these lines. Now Student model will become available in the admin area.
from django.contrib import admin from .models import Student # Register your models here. @admin.register(Student) class StudentAdmin(admin.ModelAdmin): list_display = ['id', 'name', 'roll' , 'city']
Here I am using the admin.ModelAdmin and @admin.register are used to register the Student class. list_display is the list of all fields that we want to see in our database.
3 . Next, Login into the admin and select the Student model, then create and save two or three new Students. We will need these Students later when we use the films CRUD to save new Students.
Part 4: Structure the App Routes and Class-Based Views
- Openclassbasedcrud/urls.py file. and import the include function and use it to create a new route.
First import the api views and other important libraries
from django.contrib import admin from django.urls import path from api import views
After importing the libraries, Let’s create a new route for API.
urlpatterns = [ path('admin/', admin.site.urls), path('teststu/',views.StudentAPI.as_view()), ]
Create your own path for your route, mine is called teststu/.
Note: The CBV are not created yet, so running the server at this point will generate errors.
2 . Let’s move into api/views.py, this code will create the generic CBV that we actually needed.
from django.shortcuts import render from .models import Student import io from rest_framework.parsers import JSONParser from .serializer import StudentSeralizer from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt from django.utils.decorators import method_decorator from django.views import View # Create your views here. @method_decorator(csrf_exempt,name = 'dispatch') class StudentAPI(View): def get(self,request, *args , **kwargs): json_data = request.body stream = io.BytesIO(json_data) pythondata = JSONParser().parse(stream) id = pythondata.get("id", None) if id is not None: stu = Student.objects.get(id = id) serializer = StudentSeralizer(stu) print("Serializer Data ", serializer.data) return JsonResponse(serializer.data , safe= False) stu = Student.objects.all() serializer = StudentSeralizer(stu , many= True) print("All Data Serializer", serializer.data) return JsonResponse(serializer.data, safe=False) def post(self , request , *args , **kargs): json_data = request.body stream = io.BytesIO(json_data) pythondata = JSONParser().parse(stream) serializer = StudentSeralizer(data = pythondata) if serializer.is_valid(): serializer.save() response_data = { "data" : serializer.data, "msg" : "data is sucessfully Add" } return JsonResponse(response_data, safe=False) return JsonResponse(serializer.errors, safe=False) def put(self, request, *args , **kwargs): json_data = request.body stream = io.BytesIO(json_data) pythondata = JSONParser().parse(stream) id = pythondata.get("id") stu = Student.objects.get(id=id) serializer = StudentSeralizer(stu, data = pythondata , partial= True) if serializer.is_valid(): serializer.save() response_data= { "data": serializer.data, "status": "success", } return JsonResponse(response_data, safe = False) response_data = { "data" : serializer.errors, "status" : "failed" } return JsonResponse(response_data, safe=False) def delete(self, request , *args , **kargs): json_data = request.body stream = io.BytesIO(json_data) pythondata = JSONParser().parse(stream) id = pythondata.get("id") stu = Student.objects.get(id=id) stu.delete() response_data = {"status": "success", "msg": "Data is Deleted"} return JsonResponse(response_data, safe=False)
In the above code, you can see the all CRUD code with complete implementations with all important libraries.
i. First we are importing the model Student from the models.py file
ii. I am also using Serializer in our Project. This is an important concept that we will discuss in an upcoming article.
Note: a serializer is a tool used for converting complex data types, such as QuerySets and model instances, into a format that can be easily rendered into JSON, XML, or other content types.
Serializers play an essential role in Django’s support for building APIs (Application Programming Interfaces). An API endpoint will typically receive data from a request, and the response will be serialized into the desired format, such as JSON or XML, and returned to the client.
Django provides a built-in serializer framework that allows developers to define custom serialization logic for their application’s models or data structures. This framework provides a set of classes and functions for defining the serialization behavior, validating the data, and generating the output format.
Overall, serializers in Django allow developers to easily work with complex data types and generate API responses in various formats while maintaining a consistent data structure.
18. Here is the Serializer code which we are using in our Project.
from rest_framework import serializers from .models import Student class StudentSeralizer(serializers.Serializer): name = serializers.CharField(max_length=100) roll = serializers.IntegerField() city = serializers.CharField(max_length=100) def create(self , validate_data): return Student.objects.create(**validate_data) def update(self, instance , validate_data): instance.name = validate_data.get("name", None) instance.roll = validate_data.get("roll", None) instance.city = validate_data.get("city", None) instance.save() return instance # Field validation def validate_roll(self,value): if value >= 200: raise serializers.ValidationError("Seat Full") return va def validate(self, data): name = data.get("name") city = data.get("city") if name.lower() == 'rohit' and city.lower() != 'Islamabad': raise serializers.ValidationError("Must Enter Valid Values") return data
3 . We use serializers in Django to convert complex data types, such as QuerySets and model instances, into a format that can be easily rendered into JSON, XML, or other content types. Serializers are particularly useful for building APIs (Application Programming Interfaces) as they allow us to easily serialize data into the desired format and send it as a response to client requests.
Serializers also provide additional functionality such as data validation, deserialization, and customization of serialization behavior. With serializers, we can easily transform our data between various representations, without having to write custom conversion logic for each data type. This makes our code more modular and easier to maintain.
Part 5: API’s Calling
Here are all payloads for requesting the data.
http://127.0.0.1:8000/teststu/
This URL is the base URL for all APIs. Now we just need to update our payloads to achieve our task.
Get Method { "id":1 } //The above payload is for a single and specific Student {} ########### Post Method { "name": "xyz", "roll": 2, "city": "xyz", } ########## Put Method { "id":1, "name":"xyz", "roll": 2, "city": "xyz", } ######### Delete Method { "id":1 }
Final Remarks: Make your own Djago CRUD APPS
You have now all the necessary tools to build more complex Django CRUD apps with your own models.
For example, imagine you have three tables: Institutions, Projects, and Courses. One institution can submit multiple projects and one project can have one or more courses ventilated to it.
To make a Django CRUD in this context, you just need to follow the steps we discussed above for these three entities, in a new Django project:
- Define the models in a models.py file;
- In a urls.py file, create five routes for each model, following the patterns we showed. Since we have three models, you would have fifteen routes in total, and maybe one more for a home page. You could put links in a navigation bar to go directly to the respective list of all pages of Institutions, Projects, and Courses.
- Put all the necessary code in views.py. We created six Class-based Views for Films, so we would have 18 CBV in total: 6 for Institutions, 6 for Projects, and 6 for Courses, all in the same file.
Thank you so much, dear reader, for having honored my text with your time and attention.
Happy coding!
.