Django Rest Framework:使用根 API 获取单个对象
Django Rest Framework: Get singular object using the root API
我正在尝试设置一个 API 端点,该端点 return 是一个单一对象。
现在我有:
class ShoppingCartViewSet(viewsets.GenericViewSet, mixins.ListModelMixin):
"""
API endpoint that allows users to be viewed or edited.
"""
serializer_class = ShoppingCartSerializer
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticated,)
def get_paginated_response(self, data):
return Response(data)
def get_queryset(self):
return ShoppingCart.objects.filter(user=self.request.user)
它使用 ListModelMixin
和过滤器 return 一件商品,因为每个用户都有 1 个购物车。
问题是 filter
函数 return 是一个查询集,但我只想要一个项目。
我尝试使用 RetrieveModelMixin
,但 运行 并没有在我想要的端点上使用。在 .../api/shopping-cart/id
检索 运行s 但我想在 .../api/shopping-cart
检索,因为过滤是通过登录的人完成的。
有什么解决办法吗?
我不确定你是否尝试过这个,但它应该是值得的(虽然我不确定它是否有效)
def get_queryset(self):
return ShoppingCart.objects.filter(user=self.request.user)[:1]
为什么不使用简单的 api 视图而不是视图集 class?
from django.http import Http404
from rest_framework import status, views
class ShoppingCartAPIView(views.APIView):
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticated,)
def get_object(self):
# use .get if you are really sure it can only be one shopping cart per user
try:
return ShoppingCart.objects.get(user=self.request.user)
except ShoppingCart.DoesNotExist:
raise Http404()
def get(self, request):
obj = self.get_object()
data = ShoppingCartSerializer().to_representation(obj)
return Response(data, status=status.HTTP_200_OK)
您甚至可以为其他 http 方法创建逻辑,例如 post
、delete
。
然后添加 url 模式 api/shopping-cart
正常 url(在 urls.py
中),而不是路由器模式。
我最终解决它的方法仍然是使用 ListModelMixin,因为我需要视图集的好处。
我用以下代码覆盖了 list()
方法:
class ShoppingCartViewSet(viewsets.GenericViewSet, mixins.ListModelMixin):
"""
API endpoint that allows users to be viewed or edited.
"""
serializer_class = ShoppingCartSerializer
# authentication_classes = (TokenAuthentication,)
# permission_classes = (IsAuthenticated,)
def get_paginated_response(self, data):
return Response(data)
def list(self, request, *args, **kwargs):
instance = ShoppingCart.objects.get(user=self.request.user)
serializer = self.get_serializer(instance)
return Response(serializer.data)
其中 returns 我是根 url 上的单个项目 url .../api/shopping-cart 无需传递参数,因为它根据用户进行过滤。
我正在尝试设置一个 API 端点,该端点 return 是一个单一对象。
现在我有:
class ShoppingCartViewSet(viewsets.GenericViewSet, mixins.ListModelMixin):
"""
API endpoint that allows users to be viewed or edited.
"""
serializer_class = ShoppingCartSerializer
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticated,)
def get_paginated_response(self, data):
return Response(data)
def get_queryset(self):
return ShoppingCart.objects.filter(user=self.request.user)
它使用 ListModelMixin
和过滤器 return 一件商品,因为每个用户都有 1 个购物车。
问题是 filter
函数 return 是一个查询集,但我只想要一个项目。
我尝试使用 RetrieveModelMixin
,但 运行 并没有在我想要的端点上使用。在 .../api/shopping-cart/id
检索 运行s 但我想在 .../api/shopping-cart
检索,因为过滤是通过登录的人完成的。
有什么解决办法吗?
我不确定你是否尝试过这个,但它应该是值得的(虽然我不确定它是否有效)
def get_queryset(self):
return ShoppingCart.objects.filter(user=self.request.user)[:1]
为什么不使用简单的 api 视图而不是视图集 class?
from django.http import Http404
from rest_framework import status, views
class ShoppingCartAPIView(views.APIView):
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticated,)
def get_object(self):
# use .get if you are really sure it can only be one shopping cart per user
try:
return ShoppingCart.objects.get(user=self.request.user)
except ShoppingCart.DoesNotExist:
raise Http404()
def get(self, request):
obj = self.get_object()
data = ShoppingCartSerializer().to_representation(obj)
return Response(data, status=status.HTTP_200_OK)
您甚至可以为其他 http 方法创建逻辑,例如 post
、delete
。
然后添加 url 模式 api/shopping-cart
正常 url(在 urls.py
中),而不是路由器模式。
我最终解决它的方法仍然是使用 ListModelMixin,因为我需要视图集的好处。
我用以下代码覆盖了 list()
方法:
class ShoppingCartViewSet(viewsets.GenericViewSet, mixins.ListModelMixin):
"""
API endpoint that allows users to be viewed or edited.
"""
serializer_class = ShoppingCartSerializer
# authentication_classes = (TokenAuthentication,)
# permission_classes = (IsAuthenticated,)
def get_paginated_response(self, data):
return Response(data)
def list(self, request, *args, **kwargs):
instance = ShoppingCart.objects.get(user=self.request.user)
serializer = self.get_serializer(instance)
return Response(serializer.data)
其中 returns 我是根 url 上的单个项目 url .../api/shopping-cart 无需传递参数,因为它根据用户进行过滤。