web-dev-qa-db-ja.com

モデルシリアライザーで現在のユーザーを取得する

モデルシリアライザーで現在のユーザーを取得することは可能ですか?ジェネリックから分岐する必要はありません。そうしなければならないのは、そうしなければならない単純なタスクだからです。

私のモデル:

class Activity(models.Model):
    number = models.PositiveIntegerField(
        blank=True, null=True, help_text="Activity number. For record keeping only.")
    instructions = models.TextField()
    difficulty = models.ForeignKey(Difficulty)
    categories = models.ManyToManyField(Category)
    boosters = models.ManyToManyField(Booster)

    class Meta():
        verbose_name_plural = "Activities"

私のシリアライザー:

class ActivitySerializer(serializers.ModelSerializer):

    class Meta:
        model = Activity

そして私の見解:

class ActivityDetail(generics.RetrieveUpdateDestroyAPIView):

    queryset = Activity.objects.all()
    serializer_class = ActivityDetailSerializer

応答が次のようになるように、追加フィールドuserを使用してモデルを返すにはどうすればよいですか。

{
    "id": 1, 
    "difficulty": 1, 
    "categories": [
        1
    ], 
    "boosters": [
        1
    ],
    "current_user": 1 //Current authenticated user here
}
32
Jamie Counsell

DRFソースコードを見ると答えが見つかりました。

class ActivitySerializer(serializers.ModelSerializer):

    # Create a custom method field
    current_user = serializers.SerializerMethodField('_user')

    # Use this method for the custom field
    def _user(self, obj):
        request = getattr(self.context, 'request', None)
        if request:
            return request.user

    class Meta:
        model = Activity
        # Add our custom method to the fields of the serializer
        fields = ('id','current_user')

重要なのは、ModelSerializer内で定義されたメソッドが独自のコンテキストにアクセスできるという事実です。このコンテキストには常に要求(認証されたユーザーを含む)が含まれます。私の許可は認証されたユーザーのみを対象としているため、ここには常に何かがあるはずです。

これは、他の組み込みdjangorestframeworkシリアライザーでも実行できます。

Braden Holtが指摘したように、userがまだ空の場合(つまり_userNoneを返しています。これは、コンテキストの一部としてシリアライザがリクエストで初期化されなかったためである可能性があります。これを修正するには、シリアライザを初期化するときにリクエストコンテキストを追加するだけです。

serializer = ActivitySerializer(
    data=request.data,
    context={
        'request': request
    }
)
44
Jamie Counsell

コンテキストは、RESTフレームワークにシリアライザーに渡されます。このフレームワークには、デフォルトでリクエストが含まれています。したがって、単にself.context['request'].userシリアライザー内。

37
codwell