Leveling Up with Django: A Practical Guide to Building a CRUD App

Leveling Up with Django: A Practical Guide to Building a CRUD App

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

  1. 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?https://localhost:8000,?and check if the app is working correctly.

11. Go to?https://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

  1. 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.


https://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!

要查看或添加评论,请登录

社区洞察

其他会员也浏览了