You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django多商户商城:嵌套URL获取购物车商品返回404问题

问题分析与解决方案

核心问题

你用了generics.RetrieveAPIView,这个视图是用来获取单个模型对象的,但你重写get_queryset后返回的是CartItems的QuerySet,和视图默认处理的Cart模型不匹配,导致视图尝试从CartItems里找对应pk的购物车对象时失败,返回404 Not Found。而且你的需求是获取指定购物车下的所有商品项,本身就该用列表视图而非详情视图。

修复步骤

1. 替换视图类

把RetrieveAPIView换成generics.ListAPIView,因为你要返回的是购物车商品项的列表:

from rest_framework import generics

class CartItemsRetrieveView(generics.ListAPIView):
    serializer_class = CartItemsSerializer  # 换成CartItems的序列化器,别用CartSerializer
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    pagination_class = StandardResultsSetPagination

2. 修正get_queryset方法

现在视图是列表视图,直接返回指定购物车下的所有商品项即可:

def get_queryset(self):
    cart_id = self.kwargs.get("pk")
    # 过滤出属于该购物车的商品项,购物车不存在时会返回空列表
    return CartItems.objects.filter(cart__cart_id=cart_id)

3. 调整序列化器

需要专门的CartItemsSerializer来序列化单个商品项,和你想要返回的格式对应:

from rest_framework import serializers
from .models import CartItems

class CartItemsSerializer(serializers.ModelSerializer):
    product = serializers.SerializerMethodField()

    class Meta:
        model = CartItems
        fields = ["cart_items_id", "cart", "product", "quantity", "sub_total"]
    
    def get_product(self, obj):
        return {
            "product_id": obj.product.product_id,
            "title": obj.product.title,
            "discounted_price": obj.product.discounted_price
        }

4. 可选:兼容两种需求

如果你既需要获取带商品项的购物车详情,又需要单独获取购物车的商品项列表,可以:

  • 保留原来的RetrieveAPIView(不重写get_queryset)处理购物车详情请求
  • 新建CartItemsListView(用ListAPIView)来对应/cart_retrieve/<str:pk>/items/路由

原写法报错原因

当你用RetrieveAPIView时,视图内部会:

  1. 调用get_queryset()拿到你返回的CartItems集合
  2. 尝试从这个集合里找pk和URL中参数匹配的对象
  3. 但URL里的pk是购物车的cart_id,而CartItems的主键是cart_items_id,自然找不到对应对象,返回404

内容的提问来源于stack exchange,提问作者Khaleel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 18:32:09