Django如何从Item模型获取数据并通过表单存入Addtocart购物车模型
问题原因
- 购物车模型字段命名不匹配:Addtocart模型中关联User的字段命名为大写的
User,但视图里传参用的是小写user,同时模型的__str__方法也调用的是self.user,大小写不一致会触发字段不存在的报错。
- 购物车模型字段命名不匹配:Addtocart模型中关联User的字段命名为大写的
- 用户关联字段类型错误:用
OneToOneField关联User意味着一个用户只能对应一条购物车记录,完全不符合购物车一个用户可以加多个商品的逻辑,添加第二个商品时会直接报错。
- 用户关联字段类型错误:用
- 外键赋值类型错误:post视图中通过
request.POST.get('item')拿到的是字符串类型的商品ID,直接赋值给外键字段item时,Django要求外键要么传入关联模型的实例,要么传入整数类型的主键值,类型不匹配会触发报错。
- 外键赋值类型错误:post视图中通过
- 详情页GET视图参数错误:拿单个商品时用了
filter方法返回的是查询集而非单个实例,同时给模板传参时把单个商品和全部商品的变量名搞反了,会导致模板渲染表单时拿到的商品ID错误,提交的ID本身无效。
- 详情页GET视图参数错误:拿单个商品时用了
解决方案
第一步:修正Addtocart模型
class Addtocart(models.Model): # 把OneToOneField改成ForeignKey,字段名改成小写user,保证和调用处一致 user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='cart_items') item = models.ForeignKey(Item, on_delete=models.CASCADE, related_name='cart_item') added_date = models.DateField(auto_now=True) def __str__(self): return self.user.username
修改完记得执行makemigrations和migrate命令同步数据库结构。
第二步:修正商品详情视图
class Product_detail(View): def get(self, request, item_id,): # 用get拿单个商品实例,不要用filter item = Item.objects.get(id=item_id) category_list = Categories.objects.all() items = Item.objects.order_by('-update_at') # 修正传参的变量名,避免模板里混淆 return render (request, 'product_detail.html',{"item" : item, 'category_list': category_list, 'recommend_items': items }) def post(self, request, item_id): # 先判断用户是否登录,避免匿名用户提交报错 if not request.user.is_authenticated: # 这里可以跳转到登录页,按你自己的业务逻辑调整 return redirect('login') item_id = request.POST.get('item') # 先查询对应的商品实例 try: item = Item.objects.get(id=item_id) except Item.DoesNotExist: # 商品不存在的错误处理,按需调整 return redirect('products:list') # 可选:判断该商品是否已经在当前用户购物车中,避免重复添加 if Addtocart.objects.filter(user=request.user, item=item).exists(): # 已经存在的处理,比如提示已加购,按需调整 return redirect('products:detail', item_id=item_id) # 正确创建购物车记录 Addtocart.objects.create( user=request.user, item = item ) return redirect('products:detail', item_id=item_id)
第三步:调整前端模板的变量引用
因为你GET视图的传参变量名改了,原来模板里用到全部推荐商品的地方,把原来的item变量改成recommend_items即可,表单部分不用改,现在{{item.id}}已经是正确的单个商品ID。
内容的提问来源于stack exchange,提问作者Shreyash mishra
相关产品推荐
相关产品推荐

