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

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

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에 액세스 할 수있는 방법이 필요합니다.



답변

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

이렇게 :

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

또는 더 안전하려면

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

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


답변

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

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


답변

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


답변

뷰 내부에서 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)


답변

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)


답변