Mixins & Permissions#
Mixins#
ListModelMixin#
from rest_framework.mixins import ListModelMixin
from rest_framework.viewsets import GenericViewSet
class PostListViewSet(ListModelMixin, GenericViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
# Only provides list() action
CreateModelMixin#
from rest_framework.mixins import CreateModelMixin
class PostCreateViewSet(CreateModelMixin, GenericViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
# Only provides create() action
RetrieveModelMixin#
from rest_framework.mixins import RetrieveModelMixin
class PostRetrieveViewSet(RetrieveModelMixin, GenericViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
# Only provides retrieve() action
UpdateModelMixin#
from rest_framework.mixins import UpdateModelMixin
class PostUpdateViewSet(UpdateModelMixin, GenericViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
# Only provides update() and partial_update() actions
DestroyModelMixin#
from rest_framework.mixins import DestroyModelMixin
class PostDestroyViewSet(DestroyModelMixin, GenericViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
# Only provides destroy() action
Combine Mixins#
from rest_framework.mixins import (
ListModelMixin,
CreateModelMixin,
RetrieveModelMixin,
UpdateModelMixin,
DestroyModelMixin
)
from rest_framework.viewsets import GenericViewSet
class PostViewSet(
ListModelMixin,
CreateModelMixin,
RetrieveModelMixin,
UpdateModelMixin,
DestroyModelMixin,
GenericViewSet
):
queryset = Post.objects.all()
serializer_class = PostSerializer
# Equivalent to ModelViewSet
Permissions#
Built-in Permissions#
from rest_framework.permissions import (
AllowAny,
IsAuthenticated,
IsAdminUser,
IsAuthenticatedOrReadOnly
)
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
permission_classes = [IsAuthenticated] # All actions require auth
# Or per-action
def get_permissions(self):
if self.action == 'list':
permission_classes = [AllowAny]
else:
permission_classes = [IsAuthenticated]
return [permission() for permission in permission_classes]
Custom Permissions#
# permissions.py
from rest_framework import permissions
class IsOwnerOrReadOnly(permissions.BasePermission):
"""
Custom permission: only owner can edit
"""
def has_object_permission(self, request, view, obj):
# Read permissions for any request
if request.method in permissions.SAFE_METHODS:
return True
# Write permissions only to owner
return obj.author == request.user
# views.py
from .permissions import IsOwnerOrReadOnly
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
permission_classes = [IsAuthenticated, IsOwnerOrReadOnly]
Django Model Permissions#
from rest_framework.permissions import DjangoModelPermissions
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
permission_classes = [DjangoModelPermissions]
# Requires: myapp.add_post, myapp.change_post, myapp.delete_post
Authentication#
Token Authentication#
pip install djangorestframework-simplejwt
# Or use built-in (deprecated)
# settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
],
}
# Or JWT
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
}
# views.py
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
Session Authentication#
# settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
],
}
Per-View Authentication#
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
def get_authenticators(self):
if self.action == 'list':
return [] # No auth for list
return [TokenAuthentication()] # Auth for other actions
Throttling#
# settings.py
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '100/hour',
'user': '1000/hour'
}
}
# views.py
from rest_framework.throttling import UserRateThrottle
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
throttle_classes = [UserRateThrottle]
Complete! Review Setup to get started.