Skip to content

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.