CRUD Operations Using Django REST Framework

CRUD stands for Create, Read, Update, and Delete. These are the four fundamental operations performed on data in most applications.

In Django REST Framework (DRF), CRUD operations are typically implemented using APIView, serializers, and Django models.

In this tutorial, we’ll build a complete Employee API that supports all CRUD operations.

Creating the Model

First, create an Employee model.

from django.db import models

class Employee(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField(unique=True)
    department = models.CharField(max_length=100)

    def __str__(self):
        return self.name

Run migrations:

python manage.py makemigrations
python manage.py migrate

Creating the Serializer

Create serializers.py:

from rest_framework import serializers
from .models import Employee

class EmployeeSerializer(serializers.ModelSerializer):

    class Meta:
        model = Employee
        fields = "__all__"

The serializer will handle data conversion and validation.


Create Operation (POST)

The Create operation adds a new record to the database.

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from .models import Employee
from .serializers import EmployeeSerializer

class EmployeeCreateAPIView(APIView):

    def post(self, request):

        serializer = EmployeeSerializer(data=request.data)

        if serializer.is_valid():
            serializer.save()

            return Response(
                serializer.data,
                status=status.HTTP_201_CREATED
            )

        return Response(
            serializer.errors,
            status=status.HTTP_400_BAD_REQUEST
        )

Request:

{
    "name": "Tarun Kumar",
    "email": "tarun@example.com",
    "department": "IT"
}

Response:

{
    "id": 1,
    "name": "Tarun Kumar",
    "email": "tarun@example.com",
    "department": "IT"
}

Read Operation (GET)

Read operations retrieve data from the database.

Retrieve All Records

class EmployeeListAPIView(APIView):

    def get(self, request):

        employees = Employee.objects.all()

        serializer = EmployeeSerializer(
            employees,
            many=True
        )

        return Response(serializer.data)

Response:

[
    {
        "id": 1,
        "name": "Tarun Kumar",
        "email": "tarun@example.com",
        "department": "IT"
    }
]

Retrieve Single Record

class EmployeeDetailAPIView(APIView):

    def get(self, request, pk):

        employee = Employee.objects.get(pk=pk)

        serializer = EmployeeSerializer(employee)

        return Response(serializer.data)

Request:

GET /api/employees/1/

Response:

{
    "id": 1,
    "name": "Tarun Kumar",
    "email": "tarun@example.com",
    "department": "IT"
}

Update Operation (PUT)

The PUT method updates an entire record.

class EmployeeUpdateAPIView(APIView):

    def put(self, request, pk):

        employee = Employee.objects.get(pk=pk)

        serializer = EmployeeSerializer(
            employee,
            data=request.data
        )

        if serializer.is_valid():
            serializer.save()

            return Response(serializer.data)

        return Response(serializer.errors)

Request:

{
    "name": "Tarun Kumar",
    "email": "tarun@example.com",
    "department": "HR"
}

Response:

{
    "id": 1,
    "name": "Tarun Kumar",
    "email": "tarun@example.com",
    "department": "HR"
}

Partial Update (PATCH)

PATCH updates only specific fields.

class EmployeePartialUpdateAPIView(APIView):

    def patch(self, request, pk):

        employee = Employee.objects.get(pk=pk)

        serializer = EmployeeSerializer(
            employee,
            data=request.data,
            partial=True
        )

        if serializer.is_valid():
            serializer.save()

            return Response(serializer.data)

        return Response(serializer.errors)

Request:

{
    "department": "Finance"
}

Response:

{
    "id": 1,
    "name": "Tarun Kumar",
    "email": "tarun@example.com",
    "department": "Finance"
}

Delete Operation (DELETE)

Delete removes a record from the database.

from rest_framework import status

class EmployeeDeleteAPIView(APIView):

    def delete(self, request, pk):

        employee = Employee.objects.get(pk=pk)

        employee.delete()

        return Response(
            {
                "message": "Employee deleted successfully"
            },
            status=status.HTTP_204_NO_CONTENT
        )

Request:

DELETE /api/employees/1/

Response:

{
    "message": "Employee deleted successfully"
}

Complete CRUD API in a Single View

You can also combine all operations into one APIView.

from rest_framework.views import APIView
from rest_framework.response import Response

class EmployeeAPIView(APIView):

    def get(self, request):
        pass

    def post(self, request):
        pass

    def put(self, request):
        pass

    def patch(self, request):
        pass

    def delete(self, request):
        pass

However, for larger applications, separate views are usually easier to maintain.


URL Configuration

from django.urls import path
from .views import (
    EmployeeListAPIView,
    EmployeeDetailAPIView,
    EmployeeCreateAPIView,
    EmployeeUpdateAPIView,
    EmployeeDeleteAPIView
)

urlpatterns = [
    path(
        'employees/',
        EmployeeListAPIView.as_view()
    ),
    path(
        'employees/create/',
        EmployeeCreateAPIView.as_view()
    ),
    path(
        'employees/<int:pk>/',
        EmployeeDetailAPIView.as_view()
    ),
    path(
        'employees/<int:pk>/update/',
        EmployeeUpdateAPIView.as_view()
    ),
    path(
        'employees/<int:pk>/delete/',
        EmployeeDeleteAPIView.as_view()
    ),
]

CRUD and HTTP Methods

OperationHTTP Method
CreatePOST
ReadGET
UpdatePUT
Partial UpdatePATCH
DeleteDELETE

Best Practices

  • Always use serializers for validation.
  • Return meaningful status codes.
  • Handle exceptions properly.
  • Use get_object_or_404() instead of Model.objects.get().
  • Keep business logic separate from views.
  • Use Generic Views or ViewSets for large projects.

Conclusion

CRUD operations are the foundation of most REST APIs. Django REST Framework provides powerful tools such as APIView, serializers, and ModelSerializer to efficiently implement Create, Read, Update, and Delete functionality while maintaining clean and scalable code.