You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中无法从FormView类获取URL中的Pk参数问题排查与解决

解决FormView无法获取URL中Pk参数的问题

我来帮你搞定这个问题——核心原因是你获取患者对象的时机和方式不对,FormView不会自动把URL参数绑定到类属性,而且你在类级别直接写的patient = get_object_or_404(Patient, pk)代码,会在视图类被加载时就执行,这时候请求还没进入处理流程,kwargs是空的,自然拿不到Pk值。

下面是具体的解决步骤:

1. 移除类级别的患者获取代码

首先删掉视图里这行错误的代码:

patient = get_object_or_404(Patient, pk) ***## 无法访问Pk***

这行代码执行时机太早,根本拿不到请求中的Pk参数。

2. 在请求处理阶段获取患者对象

我们可以在视图的dispatch方法或者get_context_data方法中获取患者对象,这两个方法都是在请求处理时执行的,此时self.kwargs已经包含了URL中的Pk参数。

方案一:通过dispatch存储患者对象(推荐,方便多方法复用)

修改你的OrderTestsView,重写dispatch方法提前获取患者并存在实例属性中,后续需要用的地方直接调用即可:

class OrderTestsView(FormView):
    model = Universal_Test_File
    form_class = TestOrderForm
    success_url = '/list_tests/'
    template_name = "lab/order_tests.html"

    def dispatch(self, request, *args, **kwargs):
        # 从kwargs中取出Pk,获取患者对象并存在self中
        self.patient = get_object_or_404(Patient, pk=kwargs['pk'])
        return super().dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 将患者对象添加到上下文,供模板使用
        context['patient'] = self.patient
        return context

    def form_valid(self, form):
        choice = form.cleaned_data.get("choice")
        if choice:
            for test in choice:
                # 这里可以直接使用self.patient获取患者信息
                print(f"患者Pk: {self.patient.pk}, 检测项: {test.service_id} - {test.test_name}")
        # 这里可以添加订单保存逻辑,关联当前患者
        return super().form_valid(form)

方案二:仅在get_context_data中获取(适合只在模板中展示患者信息的场景)

如果不需要在form_valid中使用患者对象,也可以直接在get_context_data里获取:

class OrderTestsView(FormView):
    model = Universal_Test_File
    form_class = TestOrderForm
    success_url = '/list_tests/'
    template_name = "lab/order_tests.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 从self.kwargs中取出Pk,获取患者对象
        patient_pk = self.kwargs.get('pk')
        context['patient'] = get_object_or_404(Patient, pk=patient_pk)
        return context

    def form_valid(self, form):
        choice = form.cleaned_data.get("choice")
        if choice:
            for test in choice:
                print(test.service_id, test.test_name)
        return super().form_valid(form)

3. 在模板中展示患者信息

修改你的order_tests.html模板,在页面顶部使用上下文里的patient对象展示信息,比如:

<div class="patient-info">
    <h3>患者信息</h3>
    <p>姓名: {{ patient.name }}</p>
    <p>患者ID: {{ patient.pk }}</p>
    <!-- 其他患者属性 -->
</div>

<!-- 表单内容 -->
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">提交检测订单</button>
</form>

这样就能在下单页面顶部正常展示患者信息,同时FormView也能正常处理表单提交了。

内容的提问来源于stack exchange,提问作者Glenn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 14:08:13