Django ORM:反向关系从单个模型查询多个模型

Django ORM: Reverse relation query multiple model from single models

我在查询反向关系时遇到了麻烦,我学到了很多关于select_relatedprefetch_related的知识,但我没有实现。

初看我的模特:

from django.db import models
import uuid

class Person(models.Model):
    alias = models.UUIDField(primary_key=True,default=uuid.uuid4, editable=False, unique=True)
    name = models.CharField(max_length=20)

class Appointment(models.Model):
    patient = models.ForeignKey(Person, related_name="patient_for_appointment", on_delete=models.CASCADE)
    data = models.CharField(max_length=20)

class Sales(models.Model):
    customer = models.ForeignKey(Person, related_name="customer_for_sales", on_delete=models.CASCADE)
    amount = models.FloatField()

class Prescription(models.Model):
    patient = models.ForeignKey(Person, related_name="Patient_for_prescription", on_delete=models.CASCADE)
    details = models.CharField(max_length=100)

我正在尝试过滤 Person 模型以检查此人是否有任何 prescriptionsalesappointment 我想通过一次查询获得所有这些喜欢这个人。将用一个人alias(主键)

过滤它

我可以用像

这样的单独查询来过滤它
patient_alias = '53fsdfsdf-fdsfds-df-fdf'
queryset = Appointment.objects.filter(
     patient__alias=patient_alias
 )

但我不想要这个,因为它有性能问题。我不希望使用单独的查询。

我只想查询 Person 模型来检查一个人是否有预约、处方或销售

喜欢Person.objects.filter(alias='a person alias)

谁能帮我实现这个目标?

非常感谢

我们可以 select 所有 Person,除了那些没有 Appointment,也没有 SalesPrescription 的 [=18] =]

Person.objects.exclude(
    patient_for_appointment=None,
    customer_for_sales=None,
    Patient_for_prescription=None
)

这将生成如下所示的查询:

SELECT person.alias, person.name
FROM person
WHERE NOT (
    person.alias IN (
        SELECT U0.alias
        FROM person U0
        LEFT OUTER JOIN prescription U1 ON U0.alias = U1.patient_id
        WHERE U1.id IS NULL
    )
    AND person.alias IN (
        SELECT U0.alias
        FROM person U0
        LEFT OUTER JOIN sales U1 ON U0.alias = U1.customer_id
        WHERE U1.id IS NULL AND U0.alias = person.alias
    )
    AND person.alias IN (
        SELECT U0.alias
        FROM person U0
        LEFT OUTER JOIN appointment U1
        ON U0.alias = U1.patient_id
        WHERE U1.id IS NULL AND U0.alias = person.alias
    )
)

或者我们可以联合起来,比如:

Person.objects.filter(
    patient_for_appointment__isnull=False
).union(
    Person.objects.filter(customer_for_sales__isnull=False),
    Person.objects.filter(Patient_for_prescription__isnull=False)
)

这将产生如下所示的查询:

(
    SELECT person.alias, person.name
    FROM person
    INNER JOIN appointment ON person.alias = appointment.patient_id
    WHERE appointment.id IS NOT NULL
) UNION (
    SELECT person.alias, person.name FROM person
    INNER JOIN sales ON person.alias = sales.customer_id
    WHERE sales.id IS NOT NULL
) UNION (
    SELECT person.alias, person.name
    FROM person
    INNER JOIN prescription ON person.alias = prescription.patient_id
    WHERE prescription.id IS NOT NULL
)