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时,视图内部会:
- 调用
get_queryset()拿到你返回的CartItems集合 - 尝试从这个集合里找
pk和URL中参数匹配的对象 - 但URL里的
pk是购物车的cart_id,而CartItems的主键是cart_items_id,自然找不到对应对象,返回404
内容的提问来源于stack exchange,提问作者Khaleel
相关产品推荐
相关产品推荐

