Упрощенное представление моих моделей:
# models.py
class User(models.Model):
first_name = models.CharField()
last_name = models.CharField()
team = models.ForeignKey('Team')
...
class Team(models.Model):
name = models.CharField()
class ToDo(models.Model):
task = models.CharField()
description = models.TextField()
owner = models.ForeignKey('User')
# serializers.py
class ToDoSerializer(serializers.ModelSerializer):
id = serializers.ReadOnlyField()
class Meta:
model = ToDo
fields = '__all__'
Я хочу создать конечную точку POST для добавления нового объекта ToDo
на основе следующей логики:
- Пользователи могут создавать
ToDo
предметов для себя - Пользователи могут создавать
ToDo
предметов для других в своей команде - Пользователи не могут создавать
ToDo
предметов для других, которых нет в ихteam
Вопрос: Где написать эту логику
Я пытался сделать это с помощью классов разрешений, но не знаю, является ли это лучшим местом длясделать это
# views.py
class ToDoViewSet(viewsets.ModelViewSet):
serializer_class = ToDoSerializer
permission_classes = (CanAddToDo,)
# permissions.py
class CanAddToDo(BasePermission):
def has_permission(self, request, view):
owner_id = request.data.get('owner', None)
# owner_id must be set
if not owner_id:
return False
# User can create items if owner is themselves or someone in their team
if User.objects.get(pk=owner_id).team == request.user.team:
return True
return False
def has_object_permission(self, request, view, obj):
"""
Checks if the user owns the todo to edit
"""
return obj.owner == request.user
Что меня беспокоит, так это то, что я не использую сериализованные данные, а вместо этого получаю необработанный идентификатор владельца из запроса и делаю запрос в объекте полномочий, чтобы выполнить мою проверку / разрешение
Другими вариантами может быть выполнение этой проверки в функции def perform_create(self, serializer):
представлений или в самом сериализаторе.