Django使用reverse_lazy生成带关联字段ID的URL跳转问题
核心问题说明
你当前代码的错误是get_success_url中传入的pk是新创建的ApplicantStatus实例的主键,而非关联的Applicant实例的主键,修复方案如下:
1. 基础跳转功能修复
直接修改ApplicantStatusCreateView的get_success_url方法,取关联申请人的主键作为参数即可:
class ApplicantStatusCreateView(LoginRequiredMixin, CreateView): model = ApplicantStatus form_class = ApplicantStatusCreateForm template_name = 'recruitment/applicant_status_create.html' def get_success_url(self): # self.object是刚创建的ApplicantStatus实例,通过外键关联取对应申请人的pk return reverse_lazy('recruitment:applicant_detail', kwargs={'pk': self.object.applicant.pk})
以上修改已经可以满足单独的申请人状态创建页提交后,跳转至对应申请人详情页的需求。
2. 详情页模态框提交场景适配
针对你在申请人详情页内嵌模态框提交的场景,有两种常用实现方案可选:
方案A:普通表单提交跳转
在模态框的表单代码中添加隐藏字段,传入当前申请人的主键,既可以作为外键赋值的依据,也可以做跳转参数兜底:
在applicant_detail.html的表单内加入:
<input type="hidden" name="applicant_id" value="{{ applicant_detail.pk }}">
然后在视图中可以优先读取该参数兜底,避免特殊情况下关联查询出错:
def get_success_url(self): applicant_pk = self.request.POST.get('applicant_id') or self.object.applicant.pk return reverse_lazy('recruitment:applicant_detail', kwargs={'pk': applicant_pk})
方案B:AJAX无刷新提交(体验更优)
模态框场景更推荐用AJAX提交,不需要页面跳转,提交成功后直接刷新当前页或者局部更新状态列表即可:
首先修改视图,适配AJAX请求:
from django.http import JsonResponse class ApplicantStatusCreateView(LoginRequiredMixin, CreateView): model = ApplicantStatus form_class = ApplicantStatusCreateForm template_name = 'recruitment/applicant_status_create.html' def form_valid(self, form): self.object = form.save() # 判断是否为AJAX请求 if self.request.headers.get('x-requested-with') == 'XMLHttpRequest': return JsonResponse({'status': 'success'}) return super().form_valid(form) def get_success_url(self): return reverse_lazy('recruitment:applicant_detail', kwargs={'pk': self.object.applicant.pk})
前端绑定表单提交事件,用AJAX提交数据,收到成功响应后关闭模态框、刷新当前页即可:
// 示例代码,可根据你实际使用的前端框架调整 $('#status-create-form').submit(function(e) { e.preventDefault(); $.post($(this).attr('action'), $(this).serialize(), function(res) { if (res.status === 'success') { $('#status-modal').modal('hide'); // 也可以替换为局部更新状态列表的逻辑,体验更好 window.location.reload(); } }) })
可选优化建议
你当前ApplicantStatus模型的外键related_name设置为applicant存在语义歧义,这个字段是用来从Applicant反向查询关联的状态列表,建议修改为statuses更符合使用习惯:
applicant = models.ForeignKey(Applicant, on_delete=models.PROTECT, related_name='statuses')
修改后你可以直接用applicant.statuses.all()查询该申请人的所有状态记录,不用再额外写过滤逻辑。
内容的提问来源于stack exchange,提问作者John Todorovic
相关产品推荐
相关产品推荐

