Build Full CRUD Endpoints with Django RetrieveUpdateDestroyAPIView (GET, PUT/PATCH, DELETE)

Last updated 3 days, 22 hours ago | 38 views 75     5

Tags:- Python Django DRF

Introduction: Why RetrieveUpdateDestroyAPIView Matters

In most RESTful APIs, there's always a need to:

  • View a resource (GET)

  • Update it (PUT/PATCH)

  • Delete it (DELETE)

Handling these separately means extra boilerplate code. Thankfully, Django REST Framework (DRF) provides a generic view called RetrieveUpdateDestroyAPIView that bundles all of this into a single, clean, and reusable class.

This article will walk you through how to use it effectively, with real code, examples, and best practices.


What Is RetrieveUpdateDestroyAPIView?

RetrieveUpdateDestroyAPIView is a DRF generic view that lets you:

  • Retrieve a single object using a GET request

  • Update the object using PUT or PATCH

  • Delete the object using a DELETE request

It’s ideal for CRUD detail views (like user profiles, articles, or products) where you want to give users full control over a specific item.


Inheritance Structure

RetrieveUpdateDestroyAPIView
│
├── GenericAPIView
├── RetrieveModelMixin   → handles GET
├── UpdateModelMixin     → handles PUT/PATCH
└── DestroyModelMixin    → handles DELETE

Step-by-Step Guide: Using RetrieveUpdateDestroyAPIView

Let’s build an API to manage blog posts. We'll support:

  • GET /posts/1/ – retrieve post detail

  • PATCH /posts/1/ – update part of a post

  • DELETE /posts/1/ – remove the post


1. Define the Model

# models.py
from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    published = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

2. Create the Serializer

# serializers.py
from rest_framework import serializers
from .models import Post

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = '__all__'

3. Build the View

# views.py
from rest_framework.generics import RetrieveUpdateDestroyAPIView
from .models import Post
from .serializers import PostSerializer

class PostDetailView(RetrieveUpdateDestroyAPIView):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

4. Add URL Routing

# urls.py
from django.urls import path
from .views import PostDetailView

urlpatterns = [
    path('posts/<int:pk>/', PostDetailView.as_view(), name='post-detail'),
]

✅ Full Functional Example

Project Structure Overview

myproject/
├── blog/
│   ├── models.py
│   ├── serializers.py
│   ├── views.py
│   └── urls.py
└── myproject/
    └── settings.py

Final View Code Recap

# views.py
from rest_framework.generics import RetrieveUpdateDestroyAPIView
from .models import Post
from .serializers import PostSerializer

class PostDetailView(RetrieveUpdateDestroyAPIView):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

How the HTTP Methods Work

Method Action Description
GET Retrieve Returns details of a specific object
PUT Update (Full) Replaces all fields with the provided data
PATCH Update (Partial) Updates only the specified fields
DELETE Destroy Removes the object from the database

Tips & Common Pitfalls

✅ Best Practices

  • Use PATCH in frontend apps to update partial data (more flexible than PUT).

  • Combine with permissions to secure sensitive endpoints:

from rest_framework.permissions import IsAuthenticated, IsAdminUser

class PostDetailView(RetrieveUpdateDestroyAPIView):
    permission_classes = [IsAuthenticated]
  • Override perform_update() and perform_destroy() to add custom behavior:

def perform_update(self, serializer):
    serializer.save(modified_by=self.request.user)

def perform_destroy(self, instance):
    # Log deletion or send notifications
    instance.delete()

❌ Common Mistakes

  • Not validating ownership: Anyone could delete/update a post unless you enforce custom permissions.

  • PUT vs PATCH confusion: PUT replaces all fields — you must include every required field.

  • Missing 404 handling: DRF handles this automatically, but don’t override get_object() unless necessary.


Example: Add Custom Permissions (Optional)

Let’s say only post owners can update or delete posts:

from rest_framework import permissions

class IsOwner(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        return obj.author == request.user

Then plug it into the view:

class PostDetailView(RetrieveUpdateDestroyAPIView):
    permission_classes = [IsAuthenticated, IsOwner]

When to Use RetrieveUpdateDestroyAPIView

✅ Ideal For:

  • Updating and deleting specific user profiles

  • Modifying and removing products or listings

  • Admin access to manage posts, comments, tickets

  • Any resource where full detail control is needed


Summary & Best Practices

  • RetrieveUpdateDestroyAPIView gives you GET + PUT/PATCH + DELETE out of the box.

  • Keep your code DRY by using generic views instead of repeating logic.

  • Secure your API with permission_classes.

  • Prefer PATCH for partial updates in modern frontend frameworks.

  • Log or hook into perform_destroy() for deletions that affect business logic.