2013-04-02 6 views
41

現在、Djangoを使用してAPIを開発中です。Django Rest Frameworkを使用して現在のユーザーを返す

私は次のエンドポイントを持つ現在のユーザを返すビューを作成したいと考えています:/users/current

これを行うには、リストビューを作成し、要求を行ったユーザーにクエリーセットをフィルタリングしました。それは動作しますが、結果はリストであり、単一のオブジェクトではありません。ページネーションと組み合わせると、結果は他のエンドポイントとあまりにも複雑で不一致に見えます。

詳細ビューを作成してクエリーセットをフィルタリングしようとしましたが、DRFはpkまたはslugを指定していないと文句を言います。

ご存知ですか?

答えて

46

このようなことをすれば、おそらく、一般的なビューから抜け出し、自分でビューを作成するのが最良です。

@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, 
     ... 
    }) 

希望します。

+1

恐ろしいのようにそれを置き換える、私は 'UserSerializer(からrequest.user)'と 'serializer.data'知りませんでした必要な認証されたなど、特定のユーザーを取得する必要がある場合建設。どうもありがとう ! – Maxime

6

私はこのような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) 
+1

elb、上記の関数を使用しようとしましたが、dispatch()が早すぎて実行されているようですが、request.userはまだ匿名です。ユーザーはディスパッチが実行された後に割り当てられます。 –

+0

これは私のためにうまく動作します。あなたは 'request.user.is_authenticated()'に 'request.user'を変更したいかもしれません。あなたがログインしていない場合、Cuz 'request.user'は' AnonymousUser'です。 –

+3

SessionAuthenticationで動作します。 TokenAuthenticationを使用しているときに機能しません。 request.userはディスパッチ内で匿名です。 – kai

5

あなたには、いくつかの理由で、一般的なビューのセットを使用する必要がある場合、あなたはこのような何かを行うことができ、

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を変更してlistメソッドを呼び出して、リストの代わりにself.retrieveを呼び出して返すようにします。

2

ModelViewSetのフルパワーを使用する代わりに、mixinを使用することができます。また、あなたのモデルを更新する必要がある場合http://www.django-rest-framework.org/api-guide/viewsets/#example_3

class UserViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet): 
    queryset = User.objects.all() 
    serializer_class = UserSerializer 

    def get_object(self): 
     return self.request.user 

、ちょうどUpdateModelMixinを追加する - それがここで言及されて同じように単一のオブジェクトを取得するために使用RetrieveModelMixinがあります。

11

最良の方法は、そのよう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は+ viewsets.GenericViewSetmixins.CreateModelMixin + mixins.RetrieveModelMixin + mixins.UpdateModelMixin + mixins.DestroyModelMixin + mixins.ListModelMixinの組み合わせです。あなただけのすべてを一覧表示したり、現在あなたはこの

class UserViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet): 
    # ... 
関連する問題