web-dev-qa-db-ja.com

Django-Rest-Frameworkシリアライザーで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にアクセスできる方法が必要です。

88
PythonIsGreat

request.userに直接アクセスすることはできません。要求オブジェクトにアクセスしてから、ユーザー属性を取得する必要があります。

このような:

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

または、より安全にするために、

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

追加のコンテキストはここで読むことができます の詳細

171
karthikr

実際には、コンテキストを気にする必要はありません。それを行うためのはるかに良い方法があります:

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

イゴールが他の回答で述べたように、使用にはCurrentUserDefaultを使用できます。このためだけにsaveメソッドをオーバーライドしたくない場合は、 doc を使用します。

from rest_framework import serializers

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

シリアライザーで小さな編集が必要です:

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)
0
cgl