Django中如何将DetailView当前对象作为外键值初始化关联创建表单
Django评论自动绑定Thread问题修复方案
报错原因
你遇到的KeyError 'pk'报错根本原因是:comment_create路由没有配置Thread的ID参数,请求该接口时self.kwargs参数字典里不存在对应ID值,自然无法取值绑定。
修复步骤
1. 修改路由配置(urls.py)
给评论创建路由增加Thread的ID参数,命名为thread_pk避免和其他模型主键混淆:
# 原来的thread详情路由保留 path('thread/<int:pk>/', views.ThreadDetailView.as_view(), name='thread-detail') # 修改评论创建路由,嵌套在thread路径下携带thread主键 path('thread/<int:thread_pk>/comment/create/', views.CommentCreate.as_view(), name='comment_create')
2. 修改详情页的评论表单提交地址
在thread_detail.html的评论表单action属性中,传入当前Thread的主键:
<form action="{% url 'comment_create' thread_pk=object.pk %}" method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">提交评论</button> </form>
3. 调整CommentCreate视图逻辑
- 移除
fields中的thread字段,不需要用户手动选择关联的Thread - 从
kwargs中取thread_pk查询到对应的Thread实例后赋值给外键 - 建议新增成功跳转逻辑,提交完成后回到当前Thread详情页
修改后的视图代码:
from django.shortcuts import get_object_or_404 from django.urls import reverse_lazy class CommentCreate(LoginRequiredMixin, CreateView): model = Comment fields = ['comment_text'] # 移除thread字段,自动绑定不需要用户输入 def form_valid(self, form): form.instance.user = self.request.user # 先校验thread_pk对应的Thread是否存在,避免无效数据 form.instance.thread = get_object_or_404(Thread, pk=self.kwargs['thread_pk']) return super().form_valid(form) # 提交成功后跳回thread详情页,可根据需求调整 def get_success_url(self): return reverse_lazy('thread-detail', kwargs={'pk': self.kwargs['thread_pk']})
(可选优化)如果不需要单独的评论详情页,可以修改Comment模型的get_absolute_url方法,直接返回关联Thread的详情地址:
def get_absolute_url(self): return reverse('thread-detail', args=[str(self.thread.id)])
内容的提问来源于stack exchange,提问作者McTrY
相关产品推荐
相关产品推荐

