Django Rest Framework:使用根 API 获取单一对象



我正在尝试设置一个返回单个对象的 API 端点。

现在我有:

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和过滤器返回一个项目,因为每个用户都有 1 个购物车。

问题是filter函数返回一个查询集,但我只想要一个项目。

我尝试使用该RetrieveModelMixin但它无法在我想要的端点上运行。检索在.../api/shopping-cart/id上运行,但我想在.../api/shopping-cart上检索,因为过滤是通过登录的人完成的。

有什么解决办法吗?

我不确定您是否尝试过这个,但它应该是值得的(尽管我不确定它是否有效(

def get_queryset(self):
return ShoppingCart.objects.filter(user=self.request.user)[:1]

为什么不使用简单的 api 视图而不是视图集类?

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 方法创建逻辑,例如postdelete

然后将 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)

它在根网址上返回一个单一的项目.../api/shopping-cart,而无需传递参数,因为它根据用户进行过滤。

最新更新