Django删除评论后重定向文章详情页报错:function object has no attribute 'format'
问题:删除评论后重定向到文章详情页触发AttributeError
我想要实现删除指定pk的评论后自动重定向到对应文章的详情页,但点击评论删除按钮时总会触发AttributeError,错误提示为function object has no attribute 'format'。如果把评论删除视图的success_url改成无参数的列表页重定向就能正常运行,但这不是我想要的效果。
相关代码
Post模型
class Post(models.Model): STATUS_CHOICES = ( ('draft', 'Draft'), ('published', 'Published'), ) title = models.CharField(max_length=250) slug = models.SlugField(max_length=250, unique_for_date='publish') author = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, related_name='blog_posts') body = models.TextField() publish = models.DateTimeField(default=timezone.now) created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True) status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='published') objects = models.Manager() published = PublishedManager() tags = TaggableManager() class Meta: ordering = ('-publish',) def __str__(self): return self.title def get_absolute_url(self): return reverse('post_detail', args=[self.pk, self.slug]) def save(self, *args, **kwargs): self.slug = slugify(self.title) super().save(*args, **kwargs)
Comment模型
class Comment(models.Model): post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments') author = models.ForeignKey(get_user_model(), on_delete=models.CASCADE,) comment = models.TextField() created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True) active = models.BooleanField(default=True) class Meta: ordering = ('created',) def __str__(self): return f'Comment by {self.author} on {self.post}' def get_absolute_url(self): return self.post.get_absolute_url() + f'#comment-{self.pk}'
CommentDeleteView视图
class CommentDeleteView(DeleteView): model = Comment template_name = 'comment_delete.html' def success_url(self): post = Post.objects.get(pk=self.object.post.pk) return post.get_absolute_url()
完整报错信息
Internal Server Error: /blog/13/comment_delete/ Traceback (most recent call last): File "C:\Users\SUNNY\blog_folder\ven\lib\site-packages\django\core\handlers\exception.py", line 34, in inner response = get_response(request) File "C:\Users\SUNNY\blog_folder\ven\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response response = self.process_exception_by_middleware(e, request) File "C:\Users\SUNNY\blog_folder\ven\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "C:\Users\SUNNY\blog_folder\ven\lib\site-packages\django\views\generic\base.py", line 71, in view return self.dispatch(request, *args, **kwargs) File "C:\Users\SUNNY\blog_folder\ven\lib\site-packages\django\views\generic\base.py", line 97, in dispatch return handler(request, *args, **kwargs) File "C:\Users\SUNNY\blog_folder\ven\lib\site-packages\django\views\generic\edit.py", line 218, in post return self.delete(request, *args, **kwargs) File "C:\Users\SUNNY\blog_folder\ven\lib\site-packages\django\views\generic\edit.py", line 212, in delete success_url = self.get_success_url() File "C:\Users\SUNNY\blog_folder\ven\lib\site-packages\django\views\generic\edit.py", line 222, in get_success_url return self.success_url.format(**self.object.__dict__) AttributeError: 'function' object has no attribute 'format' [19/Jun/2020 11:50:28] "POST /blog/13/comment_delete/ HTTP/1.1" 500 88418
问题原因与解决方案
核心原因
Django的DeleteView(以及其他通用编辑视图)中,success_url如果是类属性的话,框架会自动尝试用format方法把它和当前对象的属性进行格式化。但你在这里把success_url定义成了一个方法(函数),框架依然会把它当成字符串去调用format,自然就会抛出"函数对象没有format属性"的错误。
正确的做法是重写get_success_url()方法,而不是定义success_url函数。
修改后的代码
把你的CommentDeleteView修改成下面这样:
class CommentDeleteView(DeleteView): model = Comment template_name = 'comment_delete.html' def get_success_url(self): # 不需要重新查询Post,self.object就是当前要删除的Comment实例 return self.object.post.get_absolute_url()
说明
- 重写
get_success_url()方法是Django通用视图中自定义成功跳转地址的标准方式,框架会自动调用这个方法来获取跳转URL,而不是去尝试格式化success_url属性。 - 直接通过
self.object.post就能拿到评论对应的文章对象,不需要再用Post.objects.get()去查询,既简洁又高效。
这样修改之后,删除评论就能正确重定向到对应文章的详情页了。
内容的提问来源于stack exchange,提问作者honesty20
相关产品推荐
相关产品推荐

