web-dev-qa-db-ja.com

django RESTフレームワーク-detail_routeとdetail_listの使用

私のコードには、ユーザーのビューセットがあります。私が欲しいのは、ReadOnlyModelViewSetが正常に実行する読み取り操作(/ users/42および/ users /)のみを許可することです。

さらに、新しいユーザーを登録するために[〜#〜] post [〜#〜]にアクセスできる/ users/register URLが必要です。

class UserViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    @list_route(methods=['post'])
    def register(request):
        serializer = UserSerializer(data=request.DATA)
        if serializer.is_valid():
            user = User.objects.create_user(
                username = serializer.init_data['username'],
                password = serializer.init_data['password'],
            )

            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

いくつかの質問:

  • これは正しいやり方でしょうか?

  • list_routeまたはdetail_routeデコレータに配置した場合、メソッドに特定のsignatureはありますか? detail_routeの例では、メソッドのシグネチャは常に同じであるためです。method_name(self、request、pk = None):

ありがとう!

11
Ofek Agmon

あなたのコードはほぼ正しいです、あなたはちょうど登録メソッドに正しい署名を欠いています:

def register(self, request):

これは、 ドキュメント によると正しい署名です。さらに tests は、ルーティングに追加のパラメーターを渡すことは不可能であり、pkは常に@detail_routeなので、次のものが必要です。

@detail_route
def register(self, request, pk=None):

詳細ルートと

@list_route
def register(self, request):

リストルート用。

ただし、ModelViewSetが内部で行うように、組み込みの ViewSetMixinsを利用することをお勧めします

from rest_framework import exceptions, mixins
class UserViewSet(mixins.CreateModelMixin,
               mixins.RetrieveModelMixin,
               mixins.ListModelMixin,
               GenericViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    def create(self, request):
        serializer = UserSerializer(data=request.DATA)
            if serializer.is_valid():
                user = User.objects.create_user(
                    username = serializer.init_data['username'],
                    password = serializer.init_data['password'],
                )

                return Response(serializer.data, status=status.HTTP_201_CREATED)
            else:
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

一般的なユーザーのサインアップについては、現在プロジェクトで作業している Django-registration-restframework もご覧ください。

個人的には、プロジェクトのModelViewSetに依存しており、適切に承認されたユーザーのみが特定のアクションを実行できることを確認しています。これを行うには、モデル全体の 権限 または Djangoガーディアン と組み合わせて使用​​できます)オブジェクト固有の権限。

特にREST APIを使用すると、最終的には、特定のユーザーがすべてのリクエストを細かく管理する必要なく、特定のオブジェクトに対してのみアクションを実行できるようになります。オブジェクトレベルの権限は、ここで使用します。

13
Sebastian Wozny

detail_routeおよびdetail_listは、@ actionを使用する代わりに、DRF 3.0では非推奨になります。

from rest_framework.decorators import action
    @action(methods=['POST'], detail=True)
    def sale(self):
       ...

このメソッドがそのエンドポイントによって表されるモデルの単一のインスタンスを説明する場合は、detail = Trueを使用し、そのモデルのクエリセットを表す必要がある場合はFalseを使用します。

4
Gregory