Django ORM: объединить исключить с не в фильтре - PullRequest
0 голосов
/ 14 марта 2019

Для этой (сильно упрощенной) настройки модели Django:

class A(models.Model)

class B(models.Model)
  a = models.ForeignKey(A, null=True, blank=True)

class C(models.Model)
  b = models.ForeignKey(B, null=True, blank=True)

Я хотел бы убедиться, что для запроса на C никакие связанные объекты, не являющиеся [a1, a2], не являются частьюquery.

Что-то вроде:

qs = C.objects.exclude(b__a__NOT_in=[a1, a2]).

Я ищу , а не

qs = C.objects.filter(b__a__in=[a1, a2])

, так как мои внешние ключи обнуляются,и я также хотел бы получить случаи, когда любой из fks на пути равен нулю.

Какой самый элегантный способ решить эту проблему?

Спасибо!

1 Ответ

2 голосов
/ 14 марта 2019

Если я правильно понимаю, вам нужны экземпляры C, для которых b равно нулю или b__a равно нулю или b__a равно одному из (a1, a2). Возможное решение здесь состоит в том, чтобы использовать models.Q объект для построения or запроса, то есть:

from django.db.models import Q

query = Q(b__a__in=[a1, a2]) | Q(b__a__isnull=True) | Q(b__isnull=True)
qs = C.objects.filter(query)

или просто "ИЛИ" наборы запросов напрямую :

qs = C.objects.filter(b__a__in=[a1, a2]) | C.objects.filter(b__a__isnull=True) | C.objects.filter(b__isnull=True)

, который даст тот же SQL-запрос, но более подробный ...

...