Подтвердить что ты не робот

Как получить Request.User в сериализаторе Django-Rest-Framework?

Я пробовал что-то вроде этого, он не работает.

class PostSerializer(serializers.ModelSerializer):

    class Meta:
        model = Post

    def save(self):
        user = self.context['request.user']
        title = self.validated_data['title']
        article = self.validated_data['article']

Мне нужен способ доступа к request.user из моего класса Serializer.

4b9b3361

Ответ 1

Вы не можете напрямую обращаться к request.user. Вам нужно получить доступ к объекту запроса, а затем получить атрибут пользователя.

Вот так:

user =  self.context['request'].user

Или, чтобы быть более безопасным,

user = None
request = self.context.get("request")
if request and hasattr(request, "user"):
    user = request.user

Подробнее о дополнительный контекст можно прочитать здесь

Ответ 2

Собственно, вам не нужно беспокоиться о контексте. Это гораздо лучший способ сделать это:

from rest_framework.fields import CurrentUserDefault

class PostSerializer(serializers.ModelSerializer):

    class Meta:
        model = Post

   def save(self):
        user = CurrentUserDefault()  # <= magic!
        title = self.validated_data['title']
        article = self.validated_data['article']

Ответ 3

Как Игорь упомянул в другом ответе, использование может использовать CurrentUserDefault. Если вы не хотите переопределять метод сохранения только для этого, используйте doc:

from rest_framework import serializers

class PostSerializer(serializers.ModelSerializer):
    user = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault())
    class Meta:
        model = Post

Ответ 4

Вам нужно небольшое редактирование в вашем сериализаторе:

class PostSerializer(serializers.ModelSerializer):

    class Meta:
        model = Post

    def save(self):
        user = self.context['request'].user
        title = self.validated_data['title']
        article = self.validated_data['article']

Вот пример, использующий модели смешивания видов. В методе create вы можете найти правильный способ вызова сериализатора. Метод get_serializer правильно заполняет контекстный словарь. Если вам нужно использовать другой сериализатор, определенный в наборе представлений, см. Метод update о том, как запустить сериализатор с помощью контекстного словаря, который также передает объект запроса в сериализатор.

class SignupViewSet(mixins.UpdateModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet):

    http_method_names = ["put", "post"]
    serializer_class = PostSerializer

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        kwargs['context'] = self.get_serializer_context()
        serializer = PostSerializer(instance, data=request.data, partial=partial, **kwargs)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)    
        return Response(serializer.data)