Je développe actuellement une API utilisant Django.
Cependant, je voudrais créer une vue qui renvoie l'utilisateur actuel avec le point de terminaison suivant: /users/current/
.
Pour ce faire, j'ai créé une vue de liste et filtré l'ensemble de requêtes sur l'utilisateur qui a fait la demande. Cela fonctionne, mais le résultat est une liste, pas un seul objet. Combiné à la pagination, le résultat semble beaucoup trop compliqué et incohérent par rapport à d'autres points finaux.
J'ai également essayé de créer une vue détaillée et de filtrer le jeu de requêtes, mais DRF se plaint de n'avoir fourni ni pk ni slug.
Avez-vous une idée?
Avec quelque chose comme ça, vous feriez probablement mieux de sortir des vues génériques et d'écrire la vue vous-même.
@api_view(['GET'])
def current_user(request):
serializer = UserSerializer(request.user)
return Response(serializer.data)
Vous pouvez également faire la même chose en utilisant une vue basée sur une classe comme ça ...
class CurrentUserView(APIView):
def get(self, request):
serializer = UserSerializer(request.user)
return Response(serializer.data)
Bien sûr, il n'y a pas non plus d'obligation d'utiliser un sérialiseur, vous pouvez tout aussi bien retirer les champs dont vous avez besoin de l'instance utilisateur.
@api_view(['GET'])
def current_user(request):
user = request.user
return Response({
'username': user.username,
'email': user.email,
...
})
J'espère que ça t'as aidé.
La meilleure façon est d'utiliser la puissance de viewsets.ModelViewSet
ainsi:
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
est une combinaison de mixins.CreateModelMixin
+ mixins.RetrieveModelMixin
+ mixins.UpdateModelMixin
+ mixins.DestroyModelMixin
+ mixins.ListModelMixin
+ viewsets.GenericViewSet
. Si vous avez juste besoin de lister tout ou d'obtenir un utilisateur particulier, y compris actuellement authentifié, il vous suffit de le remplacer comme ceci
class UserViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
# ...
Si vous devez utiliser l'ensemble de vues génériques pour une raison quelconque, vous pouvez faire quelque chose comme ça,
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
est appelée lorsque le client demande une seule instance à l'aide d'un identifiant comme une clé primaire /users/10
déclencherait normalement la méthode de récupération. Récupérer lui-même appelle get_object
. Si vous souhaitez que la vue renvoie toujours le courant utilisé, vous pouvez modifier get_object
et forcer la méthode list
pour renvoyer un seul élément au lieu d'une liste en appelant et en renvoyant self.retrieve
à l'intérieur.
J'ai utilisé un ModelViewSet comme ceci:
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)
Au lieu d'utiliser toute la puissance de ModelViewSet, vous pouvez utiliser des mixins. Il y a RetrieveModelMixin utilisé pour récupérer un seul objet comme il est mentionné ici - 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
Si vous devez également mettre à jour votre modèle, ajoutez simplement UpdateModelMixin.