Django收藏夹功能两类报错排查:AttributeError与字段类型不匹配
Django拍卖网站收藏夹功能错误排查与修复
错误1:添加收藏时触发AttributeError: 'ForwardOneToOneDescriptor' object has no attribute 'id'
问题原因
add视图最后一行代码return redirect('watchlist', Watchlist.user.id)存在两处错误:
Watchlist.user是模型类的字段描述符,并非当前用户的收藏夹实例属性,无法直接访问.id;watchlist路由定义接收的是username字符串参数,但这里传的是用户id(即使写法正确也不符合路由要求)。
修复代码
将redirect参数替换为当前登录用户的username:
return redirect('watchlist', request.user.username)
错误2:访问「My WatchList」时触发Field 'id' expected a number but got 'zahrashokri'
问题原因
watchlist视图中get_object_or_404(Watchlist, pk=username)逻辑错误:
pk对应Watchlist的主键(默认是自增数字id),但传入的是字符串类型的username,类型不匹配;- 即使查询到正确的Watchlist实例,直接将其传给模板的
products变量也不符合需求——模板需要遍历收藏的产品,而Watchlist是用户的收藏夹容器,需从中取出关联的产品集合。
修复代码
修改watchlist视图,按用户username匹配收藏夹并取出关联产品:
@login_required(login_url="login") def watchlist(request, username): # 按用户username定位对应的收藏夹 watchlist = get_object_or_404(Watchlist, user__username=username) # 取出收藏夹内的所有产品 products = watchlist.watchitem.all() return render(request, 'auctions/watchlist.html', {'products': products})
额外问题修复:收藏移除功能逻辑错误
当前remove视图会直接删除用户的整个收藏夹,而非移除单个产品,需调整为:
@login_required(login_url="login") def remove(request, pid): item = get_object_or_404(List, pk=pid) user_watchlist = get_object_or_404(Watchlist, user=request.user) user_watchlist.watchitem.remove(item) messages.success(request, f"{item.title} is deleted from your watchlist.") return redirect("watchlist", request.user.username)
同时需确保模板中移除按钮的url参数正确:
product_detail.html中{% url 'remove' p.id %}需改为{% url 'remove' list.id %}(根据上下文变量名调整,确保传入的是产品id);watchlist.html中{% url 'remove' product.id %}逻辑正确,无需修改。
修改后的完整关键代码片段(views.py)
@login_required(login_url="login") def watchlist(request, username): watchlist = get_object_or_404(Watchlist, user__username=username) products = watchlist.watchitem.all() return render(request, 'auctions/watchlist.html', {'products': products}) @login_required(login_url="login") def add(request, productid): item = get_object_or_404(List, pk=productid) user_Watchlist, __ = Watchlist.objects.get_or_create(user=request.user) user_Watchlist.watchitem.add(item) return redirect('watchlist', request.user.username) @login_required(login_url="login") def remove(request, pid): item = get_object_or_404(List, pk=pid) user_watchlist = get_object_or_404(Watchlist, user=request.user) user_watchlist.watchitem.remove(item) messages.success(request, f"{item.title} is deleted from your watchlist.") return redirect("watchlist", request.user.username)
内容的提问来源于stack exchange,提问作者zahra
相关产品推荐
相关产品推荐

