Django-Rest-Framework serializer에서 Request.User를 얻는 방법은 무엇입니까?


124

나는 이와 같은 것을 시도했지만 작동하지 않습니다.

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

Serializer 클래스에서 request.user에 액세스 할 수있는 방법이 필요합니다.


DRF는 CurrentUserDefault절대적으로 ❤️입니다 django-rest-framework.org/api-guide/validators/...
andilabs

답변:


231

request.user직접 액세스 할 수 없습니다 . 요청 개체에 액세스 한 다음 사용자 속성을 가져와야합니다.

이렇게 :

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

또는 더 안전하려면

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

추가 컨텍스트 에 대한 자세한 내용은 여기에서 읽을 수 있습니다.


1
그것은 말한다NameError: name 'self' is not defined
Coderaemon

물론 이것은 수업의 맥락에서 이루어졌습니다. 당신은 클래스의 맥락에서 가장 가능성이없는
karthikr

3
내 serializer에서 validate()메서드에서 self.context는 빈 dict입니다. 왜?
David D.

14
David-아마도 오래 전에이 문제를 해결했을 것입니다. 그러나 다른 사람이이 문제를 가지고 있다면 직렬 변환기를 수동으로 구성하고 있기 때문일 수 있습니다. 일반 관계를 위해 인스턴스화 된 중첩 된 직렬 변환기에서이 문제가 발생했습니다. 문서는 serializer = NoteSerializer (value)를 수행하라고 말하지만 이것은 요청을 포함하는 컨텍스트가 아닌 인스턴스 만 전달합니다. 당신은 생성자에 kwargs로를 통과하고 그것을가 필요로하는 정보를 보낼 수 있습니다 (그것을 수행하는 방법에 대한 get_serializer 또는 GenericAPIView 참조)
존 본입

2
@ JonVaughan kwargs를 serializer 인스턴스에 전달하는 방법에 대한 자세한 내용은 ??
tyan

74

사실, 당신은 문맥에 신경을 쓸 필요가 없습니다. 더 나은 방법이 있습니다.

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

1
작동하지 않았고 Null 개체를 반환했습니다. user_edit serializers.CurrentUserDefault = ()
Enderson 제스

39

Igor가 다른 답변에서 언급했듯이 사용은 CurrentUserDefault를 사용할 수 있습니다. 이것에 대해서만 저장 방법을 재정의하지 않으려면 doc 사용하십시오 .

from rest_framework import serializers

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

문서 링크가 이제 잘못 연결되었습니다.
coler-j

동일한 예제가 포함 된 공식 DRF 문서 링크 django-rest-framework.org/api-guide/serializers/…
Paolo Melchiorre

2

뷰 내부에서 request.user호출 할 때 전달할 수 있습니다 .save(...).

class EventSerializer(serializers.ModelSerializer):

    class Meta:
        model = models.Event
        exclude = ['user']


class EventView(APIView):

    def post(self, request):
        es = EventSerializer(data=request.data)
        if es.is_valid():
            es.save(user=self.request.user)
            return Response(status=status.HTTP_201_CREATED)
        return Response(data=es.errors, status=status.HTTP_400_BAD_REQUEST)

이것은 모델입니다 :

class Event(models.Model):
    user = models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    date = models.DateTimeField(default=timezone.now)
    place = models.CharField(max_length=255)

0

serializer에서 약간의 편집이 필요합니다.

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 메소드는 컨텍스트 사전을 올바르게 채 웁니다. 뷰셋에 정의 된 다른 serializer를 사용해야하는 경우 update컨텍스트 사전을 사용하여 serializer를 시작하는 방법에 대한 메서드를 참조하세요.이 메서드는 요청 개체를 serializer에 전달합니다.

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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.