ViewSets & Routers
ViewSets combine list, create, retrieve, update, destroy into a single class. Routers automatically generate URL patterns for ViewSets. Together, they reduce your API code to just a few lines per resource.
20 min•By Priygop Team•Updated 2026
ViewSets & Routers
- ModelViewSet — Full CRUD in one class
- ReadOnlyModelViewSet — List + Retrieve only
- ViewSet — Custom actions without model binding
- Router — Auto-generates URL patterns
- DefaultRouter — Includes API root view
- router.register('prefix', ViewSet) — Register a viewset
- @action — Add custom endpoints to ViewSets
ViewSet + Router
ViewSet + Router
# blog/views.py
# from rest_framework import viewsets
# from rest_framework.decorators import action
# from rest_framework.response import Response
# from .models import Post
# from .serializers import PostSerializer
# Full CRUD ViewSet
# class PostViewSet(viewsets.ModelViewSet):
# queryset = Post.objects.all()
# serializer_class = PostSerializer
#
# def perform_create(self, serializer):
# serializer.save(author=self.request.user)
#
# def get_queryset(self):
# qs = Post.objects.filter(published=True)
# category = self.request.query_params.get('category')
# if category:
# qs = qs.filter(category__slug=category)
# return qs
#
# # Custom action: POST /api/posts/1/publish/
# @action(detail=True, methods=['post'])
# def publish(self, request, pk=None):
# post = self.get_object()
# post.published = True
# post.save()
# return Response({'status': 'published'})
#
# # Custom action: GET /api/posts/recent/
# @action(detail=False, methods=['get'])
# def recent(self, request):
# recent = Post.objects.order_by('-created_at')[:5]
# serializer = self.get_serializer(recent, many=True)
# return Response(serializer.data)
# blog/urls.py — Auto-generated URLs
# from rest_framework.routers import DefaultRouter
# router = DefaultRouter()
# router.register('posts', PostViewSet)
# # Generates: /api/posts/, /api/posts/{pk}/,
# # /api/posts/{pk}/publish/, /api/posts/recent/
# urlpatterns = router.urlsTip
Tip
Use ModelViewSet + Router for full CRUD with minimal code. One ViewSet replaces 5+ separate views.
Diagram
Loading diagram…
QuerySets are LAZY — no DB hit until evaluated.
Common Mistake
Warning
Creating separate URL patterns for each CRUD action. Use a Router with ViewSet to auto-generate all URLs.
Practice Task
Note
(1) Create a ModelViewSet. (2) Register with DefaultRouter. (3) Test all CRUD endpoints in the browsable API.
Quick Quiz
Key Takeaways
- ViewSets combine list, create, retrieve, update, destroy into a single class.
- ModelViewSet — Full CRUD in one class
- ReadOnlyModelViewSet — List + Retrieve only
- ViewSet — Custom actions without model binding