Paramclasses Academy - Blog

Tutorials Details

←
Post 22 of 29
→

Django REST Framework Generic Views and Mixins: ListAPIView, RetrieveAPIView, CreateAPIView, UpdateAPIView, and DestroyAPIView

Django REST Framework Generic Views and Mixins: ListAPIView, RetrieveAPIView, CreateAPIView, UpdateAPIView, and DestroyAPIView

October 21, 2026

Introduction

Django REST Framework (DRF) Generic Views and Mixins help developers build REST APIs with less repetitive code. Instead of manually writing every API operation, you can use reusable classes provided by DRF.

For example, ListAPIView retrieves multiple records, RetrieveAPIView retrieves one record, CreateAPIView creates new records, UpdateAPIView updates existing records, and DestroyAPIView deletes records.

DRF also provides Mixins, which contain reusable logic for common API operations. By combining generic views and mixins, developers can create clean, maintainable, and scalable APIs.

In this module, you will learn how to use generic views and mixins to build a Student Management API.

What You Will Learn

  • What generic views are in Django REST Framework.

  • What mixins are and why they are useful.

  • How to use ListAPIView.

  • How to use RetrieveAPIView.

  • How to use CreateAPIView.

  • How to use UpdateAPIView.

  • How to use DestroyAPIView.

  • How to use ListCreateAPIView.

  • How to use RetrieveUpdateDestroyAPIView.

  • How to configure URLs for generic views.

  • How to customize querysets and permissions.

  • How to reduce duplicate API code.

1. What Are Generic Views?

Generic Views are prebuilt class-based views in Django REST Framework that provide common API functionality.

In the previous module, you created separate functions for listing, creating, updating, and deleting students. Generic views let you implement many of these operations using a few lines of code.

For example, a function-based API might manually retrieve records and serialize them. With ListAPIView, much of that behavior is already provided.

Benefits of Generic Views:

  • Less repetitive code.

  • Consistent API behavior.

  • Easier maintenance.

  • Built-in serializer validation.

  • Convenient integration with authentication and permissions.

  • Simple customization through methods such as get_queryset().

2. Understanding Mixins

Mixins are reusable classes that provide specific functionality to other classes through inheritance.

Django REST Framework includes several commonly used mixins.

Mixin Purpose
ListModelMixin Lists multiple objects
RetrieveModelMixin Retrieves one object
CreateModelMixin Creates an object
UpdateModelMixin Updates an object
DestroyModelMixin Deletes an object

These mixins are commonly combined with DRF's GenericAPIView.

For example:

from rest_framework import generics, mixins

class StudentListView(
    mixins.ListModelMixin,
    generics.GenericAPIView
):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

Explanation:

  • GenericAPIView provides common API functionality, including queryset and serializer handling.

  • ListModelMixin provides the list() method.

  • The get() method calls self.list() to return the student collection.

For standard operations, you can often use a ready-made generic view instead of combining mixins manually.

3. Preparing the Student Model

This module uses a Student Management System.

Open students/models.py:

from django.db import models


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

    def __str__(self):
        return self.name

If this model already exists in your project, reuse it. Otherwise, create the migrations:

python manage.py makemigrations
python manage.py migrate

4. Creating the Student Serializer

Create or update students/serializers.py:

from rest_framework import serializers
from .models import Student


class StudentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields = ["id", "name", "email", "course"]
        read_only_fields = ["id"]

Explanation:

  • ModelSerializer generates fields based on the model.

  • fields specifies the data exposed through the API.

  • read_only_fields prevents clients from directly setting the student ID.

5. Using ListAPIView

ListAPIView retrieves multiple records and returns them as serialized data.

Add the following code to students/views.py:

from rest_framework.generics import ListAPIView
from .models import Student
from .serializers import StudentSerializer


class StudentListView(ListAPIView):
    queryset = Student.objects.all().order_by("id")
    serializer_class = StudentSerializer

Configure students/urls.py:

from django.urls import path
from .views import StudentListView

urlpatterns = [
    path(
        "students/",
        StudentListView.as_view(),
        name="student_list"
    ),
]

Open the endpoint:

http://127.0.0.1:8000/api/students/

What happens?

  1. Django matches the requested URL.

  2. ListAPIView retrieves the student records.

  3. StudentSerializer converts the records into API-compatible data.

  4. DRF returns the response, usually as JSON.

If there are no students, the endpoint returns an empty list.

6. Using RetrieveAPIView

RetrieveAPIView retrieves one object based on a lookup value, usually the primary key.

Add this class to students/views.py:

from rest_framework.generics import RetrieveAPIView


class StudentDetailView(RetrieveAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

Add the URL:

path(
    "students/<int:pk>/",
    StudentDetailView.as_view(),
    name="student_detail"
),

Example request:

GET /api/students/1/

Example JSON response:

{
    "id": 1,
    "name": "Rahul Sharma",
    "email": "rahul@example.com",
    "course": "Python"
}

If the requested student does not exist, DRF returns a 404 response.

Important: The URL parameter name pk matches the default lookup field used by the generic view.

7. Using CreateAPIView

CreateAPIView handles creating new database records through POST requests.

Add this class:

from rest_framework.generics import CreateAPIView


class StudentCreateView(CreateAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

Add the URL:

path(
    "students/create/",
    StudentCreateView.as_view(),
    name="student_create"
),

Send a POST request to:

http://127.0.0.1:8000/api/students/create/

Example JSON request:

{
    "name": "Amit Kumar",
    "email": "amit@example.com",
    "course": "Django"
}

How it works:

  1. The client sends student data.

  2. DRF passes the data to the serializer.

  3. The serializer validates the submitted values.

  4. The view saves the valid record.

  5. DRF returns the created record with HTTP status 201 Created.

If validation fails, DRF returns the corresponding errors, typically with HTTP status 400 Bad Request.

8. Using UpdateAPIView

UpdateAPIView handles updating an existing record using PUT or PATCH requests.

Add this class:

from rest_framework.generics import UpdateAPIView


class StudentUpdateView(UpdateAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

Add the URL:

path(
    "students/<int:pk>/update/",
    StudentUpdateView.as_view(),
    name="student_update"
),

PUT request example:

{
    "name": "Rahul Sharma",
    "email": "rahul@example.com",
    "course": "Advanced Django"
}

Example endpoint:

PUT /api/students/1/update/

PUT is used for a full update, so required editable fields should be provided.

PATCH request example:

{
    "course": "Advanced Python"
}

Example endpoint:

PATCH /api/students/1/update/

PATCH allows the client to update only the submitted fields.

Important: DRF's UpdateAPIView supports both PUT and PATCH by default.

9. Using DestroyAPIView

DestroyAPIView deletes a selected record through a DELETE request.

Add this class:

from rest_framework.generics import DestroyAPIView


class StudentDeleteView(DestroyAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

Add the URL:

path(
    "students/<int:pk>/delete/",
    StudentDeleteView.as_view(),
    name="student_delete"
),

Example request:

DELETE /api/students/1/delete/

A successful deletion returns HTTP 204 No Content.

Important: Protect deletion endpoints with suitable authentication and permissions. A generic view does not automatically determine whether every user should be allowed to delete every record.

10. Using ListCreateAPIView

Sometimes you want one endpoint to support both listing and creating records.

ListCreateAPIView combines the behavior of ListAPIView and CreateAPIView.

from rest_framework.generics import ListCreateAPIView


class StudentListCreateView(ListCreateAPIView):
    queryset = Student.objects.all().order_by("id")
    serializer_class = StudentSerializer

Configure the URL:

path(
    "students/",
    StudentListCreateView.as_view(),
    name="student_list_create"
),

This single endpoint supports:

  • GET to retrieve all students.

  • POST to create a new student.

Example:

GET  /api/students/
POST /api/students/

If you use this combined view, remove or replace any duplicate URL pattern that points to the previous list-only view.

11. Using RetrieveUpdateDestroyAPIView

RetrieveUpdateDestroyAPIView combines retrieval, updating, and deletion of one object.

from rest_framework.generics import RetrieveUpdateDestroyAPIView


class StudentDetailUpdateDeleteView(
    RetrieveUpdateDestroyAPIView
):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

Add the URL:

path(
    "students/<int:pk>/manage/",
    StudentDetailUpdateDeleteView.as_view(),
    name="student_manage"
),

This endpoint supports:

  • GET: Retrieve a single student.

  • PUT: Update the student's editable fields.

  • PATCH: Partially update the student.

  • DELETE: Delete the student.

Example:

GET    /api/students/1/manage/
PUT    /api/students/1/manage/
PATCH  /api/students/1/manage/
DELETE /api/students/1/manage/

Benefit: You can manage a single student's API operations without writing separate view classes for every action.

12. Understanding queryset and serializer_class

Most generic views use two important attributes.

queryset

Defines the default set of records that the view can retrieve.

queryset = Student.objects.all()

serializer_class

Defines the serializer used to validate incoming data and represent objects in API responses.

serializer_class = StudentSerializer

These attributes allow generic views to perform standard API operations with minimal code.

For more dynamic behavior, you can override get_queryset() or get_serializer_class().

13. Customizing get_queryset()

The get_queryset() method allows you to customize which records are returned.

For example, list students whose course contains the word Python.

from rest_framework.generics import ListAPIView
from .models import Student
from .serializers import StudentSerializer


class PythonStudentListView(ListAPIView):
    serializer_class = StudentSerializer

    def get_queryset(self):
        return Student.objects.filter(
            course__icontains="Python"
        ).order_by("name")

Add a URL:

path(
    "students/python/",
    PythonStudentListView.as_view(),
    name="python_students"
),

Explanation:

  • filter() selects matching records.

  • course__icontains performs a case-insensitive partial match.

  • order_by("name") sorts the results alphabetically.

This approach is useful for search pages, category filters, and dashboards.

14. Adding Authentication and Permissions

Generic views support Django REST Framework's authentication and permission system.

For example, the following view requires the user to be authenticated:

from rest_framework.generics import ListAPIView
from rest_framework.permissions import IsAuthenticated
from .models import Student
from .serializers import StudentSerializer


class ProtectedStudentListView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
    permission_classes = [IsAuthenticated]

Explanation:

  • IsAuthenticated restricts access to authenticated users.

  • Anonymous requests are denied unless authentication or permission settings are changed.

  • Authenticated users are not automatically authorized to access every record.

Security Best Practice: For private data, implement the appropriate object-level permissions and filter querysets based on the current user's access rights.

15. Understanding Generic Views vs Mixins

Feature Generic Views Mixins
Main purpose Provide ready-made API workflows Provide reusable operation logic
Example ListAPIView ListModelMixin
Code required Usually minimal Often requires combining with GenericAPIView
Best use Standard CRUD operations Custom combinations of API behavior

When should you use generic views?

Use generic views when your API follows common CRUD patterns and needs only small customizations.

When should you use mixins?

Use mixins when you need to combine selected operations or customize the request-handling workflow.

16. Common Errors and Solutions

Error 1: NameError: name 'StudentSerializer' is not defined

Solution: Import StudentSerializer from students.serializers.

Error 2: 404 Not Found

Solution: Check the URL, primary key, and whether the record exists.

Error 3: 405 Method Not Allowed

Solution: Confirm that the HTTP method is supported by the selected generic view.

For example, ListAPIView does not create records through POST. Use CreateAPIView or ListCreateAPIView if creation is required.

Error 4: 400 Bad Request

Solution: Check serializer validation errors, missing required fields, and duplicate email addresses.

Error 5: Duplicate URL patterns

Solution: Review students/urls.py and remove or reorganize overlapping routes. Ensure that each endpoint has a clear purpose and name.

Error 6: Unauthorized access

Solution: Configure authentication and permissions and verify that the requesting user is authorized to access the target record.

17. Frequently Asked Questions (FAQs)

Q1. What are generic views in Django REST Framework?

Generic views are reusable class-based views that provide common API functionality such as listing, retrieving, creating, updating, and deleting records.

Q2. What is the difference between ListAPIView and ListCreateAPIView?

ListAPIView supports listing records, while ListCreateAPIView supports both listing and creating records.

Q3. What is the purpose of RetrieveAPIView?

It retrieves a single object, usually identified by its primary key.

Q4. Does UpdateAPIView support PATCH?

Yes. It supports both PUT and PATCH requests by default.

Q5. What is the purpose of DestroyAPIView?

It deletes a selected object through a DELETE request.

Q6. Can generic views use authentication?

Yes. They support DRF authentication and permission classes.

Q7. Why are mixins useful?

Mixins provide reusable methods that can be combined with other classes to implement specific API operations without duplicating code.

18. Django REST Framework Interview Questions and Answers

Q1. What is ListAPIView?

Answer: It is a generic view used to retrieve and serialize multiple objects.

Q2. What is RetrieveAPIView?

Answer: It retrieves one object using a lookup field, commonly the primary key.

Q3. What is the difference between CreateAPIView and UpdateAPIView?

Answer: CreateAPIView creates new objects, while UpdateAPIView modifies existing objects.

Q4. What is ListCreateAPIView?

Answer: It combines list and create operations in one endpoint.

Q5. What is RetrieveUpdateDestroyAPIView?

Answer: It combines retrieving, updating, and deleting one object.

Q6. What does ListModelMixin do?

Answer: It provides the list() method for returning a collection of objects.

Q7. What is get_queryset() used for?

Answer: It customizes the queryset used by a view, for example by filtering records according to search criteria or user access.

19. Practical Assignment

Build a Student Management API using Generic Views and Mixins.

Requirements:

  1. Create a Student model with name, email, and course.

  2. Create a StudentSerializer.

  3. Use ListAPIView to retrieve all students.

  4. Use RetrieveAPIView to retrieve one student.

  5. Use CreateAPIView to create students.

  6. Use UpdateAPIView to support PUT and PATCH.

  7. Use DestroyAPIView to delete students.

  8. Create a combined endpoint using ListCreateAPIView.

  9. Create a combined detail endpoint using RetrieveUpdateDestroyAPIView.

  10. Customize one listing endpoint using get_queryset().

  11. Add authentication and appropriate permissions.

  12. Test successful requests, invalid data, missing records, and unauthorized access.

Expected Result:

You should have a working REST API that uses generic views and mixins to implement CRUD operations with clean, reusable code.

Conclusion

In this module, you learned how to use Django REST Framework Generic Views and Mixins to simplify API development. You explored ListAPIView, RetrieveAPIView, CreateAPIView, UpdateAPIView, DestroyAPIView, ListCreateAPIView, and RetrieveUpdateDestroyAPIView.

You also learned how to customize querysets, configure serializers, organize URL patterns, and protect API endpoints with authentication and permissions.

In the next module, you will learn about Django REST Framework ViewSets and Routers, including ModelViewSet, ReadOnlyModelViewSet, automatic URL generation, and organizing a REST API efficiently.

←
Post 22 of 29
→