Build Full CRUD Endpoints with Django RetrieveUpdateDestroyAPIView (GET, PUT/PATCH, DELETE)
Last updated 5 months, 3 weeks ago | 401 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
GETrequest -
Update the object using
PUTorPATCH -
Delete the object using a
DELETErequest
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
PATCHin 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:
PUTreplaces 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
-
RetrieveUpdateDestroyAPIViewgives 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
PATCHfor partial updates in modern frontend frameworks. -
Log or hook into
perform_destroy()for deletions that affect business logic.