python - Django ORM查询连接两个字段上不相关的表

标签 python django postgresql

问题

我正在编写一个程序,用于注册在各个医疗场所对患者进行的治疗。每种治疗都是针对特定的 body 部位进行的,每个医疗机构都可以定义自己的 body 部位命名方式。

我的模型如下所示:

class Treatment(Model):
    medical_place = ForeignKey(to=MedicalPlace, on_delete=PROTECT, related_name='treatments')
    body_part = CharField(max_length=64, choices=BodyPart.choices(), db_index=True)
    ... (some other fields) ...

class LocalProcedure(ProcedureBase):
    medical_place = ForeignKey(to=MedicalPlace, on_delete=PROTECT, related_name='procedures')
    identifier = CharField(verbose_name=_('Procedure number'), max_length=64, blank=False, null=False)
    description = CharField(verbose_name=_('Procedure description'), max_length=256, blank=True, null=False)
    body_part = CharField(max_length=64, choices=BodyPart.choices(), blank=False, db_index=True)

    class Meta:
        unique_together = (('body_part', 'medical_place', 'identifier'),)

我需要检索带注释的“LocalProcedure”对象列表:

  • 相关治疗次数
  • 已完成的相关治疗次数 到 X 天前(治疗模型已创建日期时间字段,但我没有 此处显示)

到目前为止我尝试过的解决方案

我可以在使用子查询时检索 LocalProcedures 的带注释列表:

    related_treatments = Treatment.objects.filter(
        body_part=OuterRef('body_part'),
        medical_places=OuterRef('medical_place'),
    ).values(
        f'body_part',
    )
    LocalProcedure.objects.annotate(
        treatments_count = Subquery(related_treatments.annotate(count=Count('pk')).values('count'),
        treatments_count = Subquery(related_treatments.filter(created__gt=now()).annotate(count=Count('pk')).values('count'),
    )

但是这个解决方案确实执行子查询,而连接这两个表(在编写原始查询时)要快得多。

感谢任何帮助。

部分工作的解决方案(最后标记为已接受)

@ruddra 在此发布的答案确实很有帮助,但并不能完全满足我的需求。我知道我通过 medical_place 字段在 LocalProcedure 和 Treatment 对象之间建立了关系,但这意味着查询将有另一个完全不必要的连接子句...

对于寻找一种无需外键即可将关系引入其模型的方法的人们 - 有一种称为 ForeignObject 的东西,可用于使用任何字段在两个对象之间创建关系。

最佳答案

也许这会简单得多:

from django.db.models import Count, F, Q

LocalProcedure.objects.annotate(
    treatments_count=Count(
        'medical_places__treatments',
        filter=Q(body_part=F('body_part'))
    ),
    treatments_count_x=Count(
        'medical_places__treatments',
        filter=Q(body_part=F('body_part'))|Q(created_gt=now())
    )
)

这里我只是使用基于 conditional expression 的过滤器进行计数.

关于python - Django ORM查询连接两个字段上不相关的表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61006889/

相关文章:

python - Heroku dynos 在部署后立即崩溃 : DATABASE undefined

django - 如何确保查询集将按有效字段排序 - django

regex - PostgreSQL regexp_replace() 只保留一个空格

Python:字符串列表,如果找到则更改字符颜色(使用 xlsxwriter)

python - 有效地就地过滤字典

python - 使用 arcpy Polyline 对象作为字典值时形状信息丢失

c# - 使用 SSL 连接到 Postgresql

python - 在 Python 中将字符串组合到数据框中的列表

python - Django NoReverseMatch

sql - 带有 RETURNS TABLE(id integer) 返回所有 NULL 的 PostgreSQL 存储过程