Build Full CRUD Endpoints with Django RetrieveUpdateDestroyAPIView (GET, PUT/PATCH, DELETE)
Last updated 3 days, 22 hours ago | 38 views 75 5

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
orPATCH
-
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 thanPUT
). -
Combine with permissions to secure sensitive endpoints:
from rest_framework.permissions import IsAuthenticated, IsAdminUser
class PostDetailView(RetrieveUpdateDestroyAPIView):
permission_classes = [IsAuthenticated]
-
Override
perform_update()
andperform_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.