Создавать экземпляр модели, только если поле id пользователя равно id вошедшего пользователя

В приложении django rest framework есть TextViewSet. Структура объекта Text выглядит следующим образом:

{
    text: text_value,
    author: author_id
}

При создании нового экземпляра Text я хочу проверить, равен ли указанный author_id идентификатору текущего зарегистрированного пользователя.

Я прочитал такой вопрос: Когда использовать Serializer's create() и ModelViewset's perform_create(), но все еще не могу решить, какой метод переопределить: Serializer's create(), ModelViewset's create() или perform_create(). Какой метод следует переопределить?

UPD:

models.py:

class Text(models.Model):
    text = models.TextField()
    author = models.ForeignKey(CustomUser, on_delete=models.CASCADE)

serializers.py:

class TextSerializer(serializers.ModelSerializer):
    class Meta:
        model = Text
        fields = ['author', 'text']

Вопрос в том, в каком из этих методов следует выполнить эту проверку if self.request.user.id != self.request.data['author']:?

Вы можете переопределить create() метод вашего TextViewSet

views.py

from rest_framework.response import Response

class TextViewSet(ModelViewSet):
    ...
    
    def create(self, request, *args, **kwargs):
    
        if self.request.user.id != self.request.data['author']:
            serializer = TextSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data)
            
            return Response({error: serializer.errors})
        
        else:
            return Response({error: "Invalid User"})
                   

Настоящий вопрос заключается в том, почему бы просто не установить author на пользователя, вошедшего в систему, и не позволять клиенту посылать какой-либо ID вообще?

Обычный способ сделать это заключается в следующем:

class MyViewSet(ModelViewSet):
    ...
    def perform_create(self, serializer):
        '''The logged in user is always the author'''
        return serializer.save(author=self.request.user)
    
    def get_queryset(self):
        '''Limit the queryset to the author, i.e the logged in user, for fetching/updating data'''
        return self.queryset.filter(author=self.request.user)

Но если вы действительно хотите передавать идентификатор автора, вы также можете использовать пользовательское разрешение для этого, чтобы его можно было использовать повторно.

from rest_framework.permissions import BasePermission

class UserIsAuthor(BasePermission):
    default_author_field = "author"

    def has_permission(self, request, view):
        author_field = getattr(
            view,
            "permission_author_field",
            self.default_author_field
        )
        return request.user.is_authenticated and (
            request.user.pk == request.data.get(author_field)
        )

используется как:

class ExampleViewSet(ModelViewSet):
    permission_classes = [UserIsAuthor]
    
    # optional if the default "author" isnt what you want.
    permission_author_field = "some_field_in_request_data" 
Вернуться на верх