簡體   English   中英

在 Django orm 中聚合多對多

[英]aggregate on many to many in django orm

我想創建一份關於本月顧問建議的持續時間的報告。 我的模型:

class Adviser(models.AbstractBaseModel):
    user = models.OneToOneField('accounts.User', on_delete=models.PROTECT, related_name='adviser')
    patients = models.ManyToManyField('patient.Patient', through='adviser.AdviserPatient', related_name='advisers')

class AdviserPatient(models.AbstractBaseModel):
    adviser = models.ForeignKey('adviser.Adviser', on_delete=models.PROTECT, related_name='adviser_patient')
    patient = models.ForeignKey('patient.Patient', on_delete=models.PROTECT, related_name='adviser_patient')
    duration = models.SmallIntegerField()
    assign_date = models.DateField(auto_now_add=True)
    release_date = models.DateField(null=True, blank=True)

class Patient(models.AbstractBaseModel):
    user = models.OneToOneField('accounts.User', on_delete=models.PROTECT, related_name='patient')

我的查詢:

ended_advise_this_mouth = Adviser.objects.annotate(
                total=Case(When(
                    adviser_patient__release_date__gte=start_of_month(),
                    adviser_patient__release_date__lte=end_of_month(),
                    then=Sum('adviser_patient__duration')), default=Value(0), output_field=IntegerField()))

但是通過這個查詢,我得到了重復的顧問:

<QuerySet [<Adviser: [1 None None]>, <Adviser: [1 None None]>, <Adviser: [1 None None]>, <Adviser: [1 None None]>, <Adviser: [1 None None]>, <Adviser: [1 None None]>, <Adviser: [2 vahid imanian]>]>

如您所見,顧問 1 以單獨的總數重復 6 次。 當我使用方法 values('id') 或使用 distinct() 時,結果不受影響。 我的數據庫是 mysql,不能使用 distinct('id')。 我需要一個用於傳遞序列化程序的查詢集,請幫我修復這個查詢,有沒有辦法為這個查詢集使用 django-rest-framework 序列化程序?

通過使用Case When ,對於每個adviser_patient行,它將檢查它是否在范圍內,並使用該單行的Sum (因此是持續時間本身),或者在超出范圍的情況下使用0

因此,您需要聚合更高的級別:

from django.db.models import IntegerField, Q, Sum, Value
from django.db.models.functions import Coalesce

# since Django-2.0
ended_advise_this_mouth = Adviser.objects.annotate(
    total=Coalesce(Sum(
        'adviser_patient__duration',
        filter=Q(
            adviser_patient__release_date__gte=start_of_month(),
            adviser_patient__release_date__lte=end_of_month()
        ),
        output_field=IntegerField()
    ), Value(0))
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM