Django 子查询和聚合

时间:2021-03-19 14:40:04

标签: django django-queryset

我有三个模型 - PatientPrescriptionMedicinePatient 可以有零个或多个 PrescriptionPrescription 可以有零个或多个 MedicineMedicine 有一个 duration 字段,表示服药的天数。

如果我们说,两个 Prescription 和两个 Medicine,每个 duration 分别为 15、15 和 15、30,那么最大处方持续时间< /em> 对于 2 个 Prescription 分别是 15 和 30。那个 Patient总用药时间是 15 + 30 = 45。

现在我想过滤 Patient 查询集以查找 总用药持续时间至少是某个指定值的所有 Patient。以下是我正在尝试的代码(使用 Django 3)。但是,以上面的例子为例,我得到的总用药时间是 30,而不是 45。

from django.db import models
from django.db.models import Subquery, OuterRef, Max, Sum


class Patient(models.Model):
    name = models.CharField(max_length=300)
    # ...


class Prescription(models.Model):
    patient = models.ForeignKey(
        Patient,
        related_name="prescriptions"
        on_delete=models.CASCADE
    )
    # ...


class Medicine(models.Model):
    prescription = models.ForeignKey(
        Prescription,
        related_name="medicines"
        on_delete=models.CASCADE
    )
    duration = models.PositiveIntegerField()
    # ...


def get_patients_with(minimum_medication_duration=365):
    patient_qs = (
        Patient.objects
        .annotate(total_medication_duration=Subquery(
            Prescription.objects
            .filter(patient=OuterRef('pk'))
            .values('patient__pk')
            .annotate(max_prescription_durations=Subquery(
                Medicine.objects
                .filter(prescription=OuterRef('pk'))
                .values('prescription__pk')
                .annotate(max_duration=Max('duration'))
                .values('max_duration')
            ))
            .annotate(total_medication_duration=Sum('max_prescription_durations'))
            .values('total_medication_duration')
        ))
        .filter(total_medication_duration__gte=minimum_medication_duration)
    )
    return patient_qs

我错过了什么?

0 个答案:

没有答案