Django评论功能报错:TypeError 'dict'对象不可调用
遇到的问题:访问
/post/3/comment/执行POST请求时触发TypeError: 'dict' object is not callable,Django版本为2.1.7,请求URL为http://localhost:8000/post/3/comment/。
相关代码
模型类
class Comment(models.Model): post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments') author = models.CharField(max_length=200) text = models.TextField() image = models.ImageField(upload_to='Comment_Pictures', blank=True) date_posted = models.DateTimeField(default=timezone.now) def __str__(self): return self.text def get_absolute_url(self): return '/'
视图类
class CommentAddView(LoginRequiredMixin, CreateView): model = Comment fields = ['text', 'image'] def form_valid(self, form): form.instance.author = self.request.user form.instance.post = Post.objects.get(id=self.kwargs['pk']) return super().form_valid(form) class CommentDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView): model = Comment success_url = '/' def test_func(self): comment = self.get_object() if request.user == comment.author: return True return False
错误原因排查
1. URL配置错误(当前触发错误的核心原因)
最可能的情况是你的urls.py中,对/post/<int:pk>/comment/路径的配置有误——你可能直接使用了字典或者错误的对象作为视图,而没有正确调用类视图的as_view()方法。比如错误的配置可能是:
# 错误示例 path('post/<int:pk>/comment/', {'model': Comment, 'fields': ['text', 'image']}),
当Django尝试处理请求时,会把这个字典当作视图函数去调用,自然会抛出'dict' object is not callable的错误。
2. CommentDeleteView中的潜在错误
虽然这不是当前触发的错误,但你的CommentDeleteView的test_func方法存在问题:直接使用request.user会导致NameError,因为在类视图中,请求对象需要通过self.request获取。
解决方法
1. 修复URL配置
确保在urls.py中正确配置CommentAddView,调用as_view()方法来生成可调用的视图函数:
# 正确示例 from django.urls import path from .views import CommentAddView, CommentDeleteView urlpatterns = [ # 其他URL配置... path('post/<int:pk>/comment/', CommentAddView.as_view(), name='comment-add'), path('comment/<int:pk>/delete/', CommentDeleteView.as_view(), name='comment-delete'), ]
2. 修复CommentDeleteView的test_func方法
修改test_func中的请求对象获取方式:
def test_func(self): comment = self.get_object() if self.request.user == comment.author: return True return False
额外优化建议
你的
Comment模型中author字段使用了CharField,但实际上应该关联User模型,这样更符合Django的用户体系:# 修改Comment模型的author字段 from django.contrib.auth.models import User author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='comments')这样在
CommentAddView的form_valid中,form.instance.author = self.request.user的逻辑会更严谨,避免字符串匹配的问题。可以为
Post.objects.get(id=self.kwargs['pk'])添加异常处理,防止传入不存在的pk导致DoesNotExist错误:def form_valid(self, form): form.instance.author = self.request.user try: form.instance.post = Post.objects.get(id=self.kwargs['pk']) except Post.DoesNotExist: # 处理Post不存在的情况,比如返回错误页面或重定向 return HttpResponseRedirect(reverse('post-list')) return super().form_valid(form)
内容的提问来源于stack exchange,提问作者Yukeshkumar

