问题
我正在编写一个程序,用于注册在各个医疗场所对患者进行的治疗。每种治疗都是针对特定的 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/