現在、Djangoを使用してAPIを開発しています。
ただし、次のエンドポイントを持つ現在のユーザーを返すビューを作成したいと思います:/users/current/
。
そのために、リストビューを作成し、要求を行ったユーザーのクエリセットをフィルター処理しました。それは機能しますが、結果は単一のオブジェクトではなくリストです。ページネーションと組み合わせた結果は、他のエンドポイントと比較して複雑すぎて一貫性がありません。
また、詳細ビューの作成とクエリセットのフィルタリングを試みましたが、DRFはpkまたはslugを提供しなかったと文句を言います。
何かアイデアはありますか?
このようなものを使用すると、おそらく汎用ビューから抜け出し、自分でビューを作成するのが最善です。
@api_view(['GET'])
def current_user(request):
serializer = UserSerializer(request.user)
return Response(serializer.data)
クラスベースのビューを使用して同じことを行うこともできます...
class CurrentUserView(APIView):
def get(self, request):
serializer = UserSerializer(request.user)
return Response(serializer.data)
もちろん、シリアライザーを使用する必要もありません。ユーザーインスタンスから必要なフィールドを引き出すこともできます。
@api_view(['GET'])
def current_user(request):
user = request.user
return Response({
'username': user.username,
'email': user.email,
...
})
お役に立てば幸いです。
最善の方法は、viewsets.ModelViewSet
の力を次のように使用することです。
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
def get_object(self):
pk = self.kwargs.get('pk')
if pk == "current":
return self.request.user
return super(UserViewSet, self).get_object()
viewsets.ModelViewSet
は、mixins.CreateModelMixin
+ mixins.RetrieveModelMixin
+ mixins.UpdateModelMixin
+ mixins.DestroyModelMixin
+ mixins.ListModelMixin
+ viewsets.GenericViewSet
の組み合わせです。すべてをリストするか、現在認証されている特定のユーザーを取得する必要がある場合は、このように置き換える必要があります
class UserViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
# ...
何らかの理由で汎用ビューセットを使用する必要がある場合は、次のようなことができます。
class UserViewSet(viewsets.ModelViewSet):
model = User
serializer_class = UserSerializer
def get_object(self):
return self.request.user
def list(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
retrieve
メソッドは、クライアントが主キーなどの識別子を使用して単一のインスタンスを要求すると呼び出されます/users/10
は、通常は検索メソッドをトリガーします。自身を取得すると、get_object
が呼び出されます。ビューが常に使用されている現在の値を返すようにする場合は、get_object
を変更し、self.retrieve
を呼び出して返すことにより、リストではなく単一のアイテムを返すようにlist
メソッドを強制できます。
次のようなModelViewSetを使用しました。
class UserViewSet(viewsets.ModelViewSet):
model = User
serializer_class = UserSerializer
def dispatch(self, request, *args, **kwargs):
if kwargs.get('pk') == 'current' and request.user:
kwargs['pk'] = request.user.pk
return super(UserViewSet, self).dispatch(request, *args, **kwargs)
ModelViewSetの全機能を使用する代わりに、ミックスインを使用できます。ここに記載されているように、単一のオブジェクトを取得するために使用されるRetrieveModelMixinがあります- http://www.Django-rest-framework.org/api-guide/viewsets/#example_
class UserViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
permission_classes = (permissions.IsAuthenticated,)
queryset = User.objects.all()
serializer_class = UserSerializer
def get_object(self):
return self.request.user
モデルも更新する必要がある場合は、UpdateModelMixinを追加するだけです。