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

其中 returns 我是根 url 上的单个项目 url .../api/shopping-cart 无需传递参数,因为它根据用户进行过滤。