Проблема
Я пишу программу, в которой регистрирую процедуры, проводимые для пациентов в различных медицинских учреждениях. Каждое лечение проводится на определенной части тела, и каждое медицинское место может определять свой собственный способ именования этих частей тела.
Мои модели выглядят так:
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 дней go (модель обработок создала поле даты и времени, которое я здесь не показывал)
Решения, которые я пробовал до сих пор
Я могу получить аннотированный список 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, был действительно полезным, но не полностью удовлетворяет мою потребность. Я знаю, что у меня есть связь между LocalProcedure и объектом Treatment через поле medical_place
, но это означает, что в запросе будет другое, совершенно ненужное предложение соединения ...
Что касается людей, которые ищут способ ввести отношения в их модели без ForeignKey - есть то, что называется ForeignObject
и может использоваться для создания отношений между двумя объектами с использованием любых полей.