Django收藏夹功能异常:点击按钮跳转后帖子未保存
Django收藏夹添加功能故障排查与修复
你的核心问题是模型字段与视图参数不匹配,导致无法正确创建收藏关联记录,同时代码中还有几处细节错误需要修正,以下是具体问题和修复方案:
问题分析
- 模型字段与视图参数不匹配:Wishlist模型中关联Posts的字段是
wished_item,但视图addToWishList中创建/查询时误用了post参数,Django无法识别该字段,因此无法保存关联数据。 __str__方法缩进错误:Wishlist类的__str__方法未缩进在类内部,属于全局函数,无法被模型实例调用(虽不影响核心功能,但需修正)。- 异常处理不精确:使用裸
except捕获所有异常,可能掩盖其他错误(如帖子不存在、ID格式错误等)。 - 冗余操作:已存在的收藏项调用
save()无意义,因为未修改任何字段。
修复后的代码
1. models.py 修正
class Wishlist(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) wished_item = models.ForeignKey(Posts, on_delete=models.CASCADE) # 修正缩进:将__str__方法放入类内部 def __str__(self): return self.wished_item.title # 可选:添加唯一性约束,避免同一用户重复收藏同一帖子 class Meta: constraints = [ models.UniqueConstraint(fields=['user', 'wished_item'], name='unique_wishlist_entry') ] class Posts(models.Model): TYPE = Choices( ('private', _('private')), ('business', _('business')), ) STATUS = Choices( ('active', _('active')), ('deactivated', _('deactivated')) ) owner = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, related_name='posts', on_delete=models.CASCADE, verbose_name='owner') phone_number = PhoneNumberField(verbose_name=_('Phone_number'), null=False, blank=False, unique=True) title = models.CharField(verbose_name=_('Title'), max_length=100) text = RichTextField(verbose_name=_('Text')) image = models.ImageField(upload_to='images/%Y/%m/%d/', null=True, blank=True, validators=[file_size]) price = models.DecimalField(verbose_name=_('Price'), decimal_places=2, max_digits=9) status = models.CharField(choices=STATUS, max_length=50) created = models.DateTimeField(auto_now=True) type = models.CharField(choices=TYPE, max_length=50) def __str__(self): return self.title
2. views.py 修正
class WishListView(generic.View): def get(self, *args, **kwargs): wish_items = Wishlist.objects.filter(user=self.request.user) context = { 'wish_items': wish_items } return render(self.request, 'wishlist/wishlist.html', context=context) def addToWishList(request): if request.method == 'POST': post_var_id = request.POST.get('object-id') # 校验ID格式,避免无效输入 try: post_var_id = int(post_var_id) except (ValueError, TypeError): return HttpResponseRedirect(reverse('wishlist')) # 校验帖子是否存在 try: post_var = Posts.objects.get(id=post_var_id) except Posts.DoesNotExist: return HttpResponseRedirect(reverse('wishlist')) # 简化逻辑:用get_or_create替代try-except,自动处理存在/不存在的情况 Wishlist.objects.get_or_create(user=request.user, wished_item=post_var) return HttpResponseRedirect(reverse('wishlist'))
3. 其他注意事项
- 模板中的表单逻辑是正确的,
object-id字段已正确传递帖子ID,无需修改。 - 若添加了模型的唯一性约束,
get_or_create会自动跳过重复创建的操作,无需额外判断。
内容的提问来源于stack exchange,提问作者makim
相关产品推荐
相关产品推荐

