创建Django评论表单触发ValueError:Comment.post需为post实例而非类
Django评论表单ValueError问题解决办法
嘿,我一眼就看出问题出在哪了!你遇到的这个Cannot assign "<class 'blog.models.post'>": "Comment.post" must be a "post" instance错误,核心原因是你在视图里把评论关联到了模型类,而不是具体的帖子实例。
问题根源拆解
看你的views.py代码:
po = get_object_or_404(post, slug=slug) # ... comment.post = post return redirect('blog:post', slug=post.slug)
你用po = get_object_or_404(...)已经拿到了当前帖子的具体实例,但后面赋值时却写了comment.post = post——这里的post是你的模型类(class post(models.Model)),不是刚才获取的实例,Django自然会报错,因为Comment.post字段需要的是一个具体的帖子对象,而不是类本身。
修正步骤
- 修改视图里的实例赋值
把视图里的错误赋值和redirect里的引用都改成你已经获取到的实例po,或者干脆把变量名改成更清晰的post_instance,避免和模型类名混淆:
修正后的views.py:
def add_comment(request, slug): post_instance = get_object_or_404(post, slug=slug) # 变量名更清晰 if request.method == 'POST': form = CommentForm(request.POST) if form.is_valid(): comment = form.save(commit=False) comment.post = post_instance # 关联到具体实例 comment.save() return redirect('blog:post', slug=post_instance.slug) # 用实例的slug else: form = CommentForm() return render(request, 'blog/post/add_comment.html', {'form': form})
- (可选但推荐)规范模型类命名
Django里模型类一般用大驼峰命名(比如Post而不是post),这样能彻底避免类名和变量名混淆的问题。给你的models.py也做个小调整:
修正后的models.py片段:
class Post(models.Model): # 大驼峰命名 # 你的Post模型字段... pass class Comment(models.Model): post = models.ForeignKey(Post, related_name='comments', on_delete=models.CASCADE) # 引用Post类 user = models.CharField(max_length=250) email = models.EmailField() body = models.TextField() created = models.DateTimeField(auto_now_add=True) approved = models.BooleanField(default=False) def approve(self): # 注意你之前的方法名和字段名重复了,改成approve更合理 self.approved = True self.save() def __str__(self): return self.user
另外注意你之前的approved方法和字段名重名了,容易引发问题,改成approve更合适。
这样修改后,你的评论表单应该就能正常提交,不会再触发那个ValueError啦!
内容的提问来源于stack exchange,提问作者Ann
相关产品推荐
相关产品推荐

