Django REST API

Custom Permissions

Custom permissions can be provided by extending the BasePermissions class and implementing the has_permission method:

from rest_framework import permissions

class IsHangoutOwner(permissions.BasePermission):
    '''Check if the user is the owner of the hangout'''

    def has_permission(self, request, view):
        return request.user.is_hangout_owner

Custom Serializers

from django_shortcuts import get_object_or_404
from core.models import User
from rest_framework import serializers

class MuteUser(serializers.Serializer):
    '''Serializer to mute a user'''
    email = serializers.CharField(required=True)

    def update(self, instance, validated_data):
        request = self.context['request']

        # Get user from same hangout
        user = get_object_or_404(User, email=email, user__hangout=request.user.hangout)
        user.is_muted = True
        user.save()
        return user

Custom Mixins

Custom mixins provide a way to reuse method overrides across views:

class MultipleFieldLookupMixin:
    """
    Apply this mixin to any view or viewset to get multiple field filtering
    based on a `lookup_fields` attribute, instead of the default single field filtering.
    """
    def get_object(self):
        queryset = self.get_queryset()             # Get the base queryset
        queryset = self.filter_queryset(queryset)  # Apply any filter backends
        filter = {}
        for field in self.lookup_fields:
            if self.kwargs[field]: # Ignore empty fields.
                filter[field] = self.kwargs[field]
        obj = get_object_or_404(queryset, **filter)  # Lookup the object
        self.check_object_permissions(self.request, obj)
        return obj

Custom Overrides

from rest_framework.generic import RetrieveUpdateDestroyView
class UserHangoutView(RetrieveUpdateDestroyView):
    ...

    def get_object(self):

    def put(self, request, *args, **kwargs):
        result = super().put(request, *args, **kwargs)
        analytics.track(f'Updated {self.request.user} in hangout {self.request.user.hangout}')
        return result