2013-04-02 2 views
41

Obecnie rozwijam API za pomocą Django.Zwraca bieżącego użytkownika z Django Rest Framework

Jednak pod numerem, chciałbym utworzyć widok, który zwróci bieżącego użytkownika z następującym punktem końcowym: /users/current.

W tym celu utworzyłem widok listy i przefiltrowałem zestaw zapytań do użytkownika, który wysłał żądanie. To działa, ale wynikiem jest lista, a nie pojedynczy obiekt. W połączeniu z paginacją wynik wygląda na zbyt skomplikowany i niespójny z innymi punktami końcowymi.

Próbowałem również utworzyć widok szczegółów i filtrowanie zestawu zapytań, ale DRF skarży się, że nie dostarczyłem pk ani ślimaka.

Masz jakiś pomysł?

Odpowiedz

46

Z czymś takim prawdopodobnie najlepiej jest wyrwać się z ogólnych widoków i napisać samemu.

@api_view(['GET']) 
def current_user(request): 
    serializer = UserSerializer(request.user) 
    return Response(serializer.data) 

Można również zrobić to samo przy użyciu widoku oparciu klasy jak tak ...

class CurrentUserView(APIView): 
    def get(self, request): 
     serializer = UserSerializer(request.user) 
     return Response(serializer.data) 

Oczywiście, istnieje również żaden wymóg, aby użyć serializatora, można równie dobrze po prostu wyciągnąć poza polami, których potrzebujesz od instancji użytkownika.

@api_view(['GET']) 
def current_user(request): 
    user = request.user 
    return Response({ 
     'username': user.username, 
     'email': user.email, 
     ... 
    }) 

Nadzieję, że pomaga.

+1

Awesome, nie wiedziałem o 'UserSerializer (request.user)' i 'serializer.data' budowa. Wielkie dzięki ! – Maxime

6

użyłem ModelViewSet tak:

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, próbowałem użyć powyższej funkcji, ale wydaje się, że dispatch() działa zbyt wcześnie, że request.user jest wciąż anonimowy, użytkownik jest przypisany po uruchomieniu wysyłki .. czy jest jakaś alternatywa dla tego? –

+0

Ten działa dobrze dla mnie. Możesz zmienić 'request.user' na' request.user.is_authenticated() '. Ponieważ 'request.user' jest' AnonymousUser', jeśli nie jesteś zalogowany. –

+3

Działa z uwierzytelnianiem sesji. Nie działa przy użyciu uwierzytelniania Token. request.user jest anonimowy wewnątrz wysyłki. – kai

5

Jeśli trzeba użyć rodzajowe zestaw widok z jakiegoś powodu, można zrobić coś takiego,

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 metoda jest wywoływana, gdy klient żąda pojedynczej instancji z użyciem identyfikatora takiego jak klucz podstawowy /users/10, który normalnie uruchomi metodę pobierania. Odzyskaj sam połączenia get_object. Jeśli chcesz, aby widok zawsze zwracał używany prąd, możesz zmodyfikować metodę get_object i wymusić metodę list, aby zwrócić pojedynczy element zamiast listy, wywołując i zwracając w nim self.retrieve.

2

Zamiast używać pełnej mocy narzędzia ModelViewSet, można użyć mixins. Jest RetrieveModelMixin używany do pobierania pojedynczego obiektu, tak jak to wspomniano tutaj - 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 

Jeśli potrzebujesz także aktualizować swój model, wystarczy dodać UpdateModelMixin.

11

Najlepszym sposobem jest użycie siły z viewsets.ModelViewSet tak:

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 jest kombinacją mixins.CreateModelMixin + mixins.RetrieveModelMixin + mixins.UpdateModelMixin + mixins.DestroyModelMixin + mixins.ListModelMixin + viewsets.GenericViewSet.Jeśli potrzebujesz tylko wymienić wszystkie lub dostać konkretnego użytkownika, w tym aktualnie uwierzytelnione trzeba tylko zastąpić go tak

class UserViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet): 
    # ...