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

Django ListView缺失QuerySet报错:单视图展示两个模型数据的问题求助

解决Django ListView缺少QuerySet的错误并展示两个模型数据

首先,咱们先拆解你遇到的ImproperlyConfigured错误:Django的ListView有个硬性规则——必须指定model、queryset,或者重写get_queryset()方法,它才能明确主数据集的来源。你的PatientListView只设置了模板路径,没满足这个要求,所以触发了报错。另外,你在get_context_data里的写法也有问题:super().get_context_data(**kwargs)返回的是上下文字典,不能直接调用.filter()方法,这会导致额外的逻辑错误。

下面是具体的修复步骤:

1. 修正views.py中的PatientListView

from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, DeleteView, CreateView
from django.urls import reverse_lazy
from bootstrap_datepicker_plus import DatePickerInput, TimePickerInput
from django.contrib.auth import get_user_model
from django.shortcuts import render
from scripts.models import Patient, Script
# 注意:删除重复的导入语句,避免冗余
# from .models import Script, Patient

class PatientListView(LoginRequiredMixin, ListView):
    template_name = 'patient_summary.html'
    # 第一步:指定主模型,满足ListView的配置要求
    model = Patient
    # 也可以用重写get_queryset的方式替代上面的model配置,效果一致:
    # def get_queryset(self):
    #     return Patient.objects.filter(author=self.request.user)

    def get_context_data(self, **kwargs):
        # 先获取默认上下文,不要在这里调用filter方法
        context = super().get_context_data(**kwargs)
        # 将两个模型的用户专属数据添加到上下文,用复数命名更清晰
        context['patients'] = Patient.objects.filter(author=self.request.user)
        context['scripts'] = Script.objects.filter(author=self.request.user)
        return context

2. 修正HTML模板(patient_summary.html)

原来的模板里,你两次遍历object_list,但object_list默认是ListView主模型(Patient)的数据集,所以第二个循环拿不到Script的数据。咱们改成直接使用上下文里的patients和scripts变量:

<!-- 展示所有Patient数据 -->
{% for patient in patients %}
<div class="card">
  <div class="card-header">
    <span class="font-weight-bold">{{ patient.patient_name }}</span>
    ·
    <span class="text-muted"></span>
  </div>
  <div class="card-body">
    Cycle Start Date - {{ patient.cycle_start_day }} <br>
  </div>
  <div class="card-footer text-center text-muted">
  </div>
</div>
<br />
{% endfor %}

<!-- 展示所有Script数据 -->
{% for script in scripts %}
<div class="card">
  <div class="card-header">
    <span class="font-weight-bold">{{ script.drug_name }}</span>
  </div>
  <div class="card-body">
    Drug Name - {{ script.drug_name }} <br>
  </div>
</div>
<br />
{% endfor %}

如果你的需求是每个Patient对应关联的Script(比如Patient和Script通过外键绑定),可以调整成嵌套循环,让数据展示更合理:

{% for patient in patients %}
<div class="card">
  <div class="card-header">
    <span class="font-weight-bold">{{ patient.patient_name }}</span>
  </div>
  <div class="card-body">
    Cycle Start Date - {{ patient.cycle_start_day }} <br>
    <h5>关联药品记录:</h5>
    <!-- 假设Script的外键字段名为patient -->
    {% for script in patient.script_set.all %}
      Drug Name - {{ script.drug_name }} <br>
    {% empty %}
      暂无药品记录
    {% endfor %}
  </div>
  <div class="card-footer text-center text-muted">
  </div>
</div>
<br />
{% endfor %}

补充说明

  • 指定model = Patient就能解决错误的原因:Django会自动根据model生成默认的queryset(即Patient.objects.all()),虽然咱们在get_context_data里又过滤了当前用户的数据,但只要满足ListView的配置要求,就能避免报错。
  • 用复数命名上下文变量(patients、scripts)是Python/Django的常用规范,能避免和单个对象混淆,提升代码可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 17:32:47