Django ListView实现添加商品到购物车提示无匹配查询如何解决?
问题根源
DetailView 对应的 URL 规则中默认携带 <int:pk> 路径参数,发起请求时 pk 会自动传入视图的 kwargs,因此可以正常获取到商品 id。而 ListView 对应的 URL 是列表页根路径,没有内置的 pk 路径参数,你从 self.kwargs 中获取到的 pk 为 None,查询 Item 时自然匹配不到数据,所以抛出 No Item matches the given query 错误;将 post 方法定义为需要 pk 参数时,由于 URL 没有传入该参数,自然会报参数缺失错误。
解决方案
需要在列表页的每个商品的提交表单中,新增隐藏字段传递当前商品的 id,后端从 POST 请求体中获取商品 id 即可。
1. 修改列表页模板(shop/home.html)
给每个商品的加入购物车表单添加隐藏的 item_id 字段:
{% for item in items %} <div class="item-card"> <!-- 商品原有展示内容 --> <form method="post"> {% csrf_token %} <input type="hidden" name="item_id" value="{{ item.pk }}"> <button type="submit">加入购物车</button> </form> </div> {% endfor %}
2. 修改 ShopListView 的 post 方法
从 POST 请求参数中获取商品 id,而非从 URL kwargs 获取:
class ShopListView(ListView): model = Item template_name = 'shop/home.html' context_object_name = 'items' def post(self, request, *args, **kwargs): item_id = request.POST.get('item_id') item = get_object_or_404(Item, id=item_id) orderItem, created = OrderItem.objects.get_or_create(order_item=item) order, created = Order.objects.get_or_create(order_user=request.user) order.order_items.add(orderItem) return HttpResponse('Items added')
补充优化
get_or_create 方法返回的已存在/新创建的实例默认已经保存到数据库,你原有代码中的 order.save() 是多余的,可以直接删除。
内容的提问来源于stack exchange,提问作者user16476339
相关产品推荐
相关产品推荐

