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
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 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
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