Django - Queryset, охватывающий нулевые отношения, используя Q

Рассмотрим модели:

#Models
class A(models.Model):
    fieldOfA = models.CharField(max_length = 4)
class B(models.Model):
    fieldOfB = models.CharField(max_length = 4)
class C(models.Model):
    classA = models.ForeignKey(A, blank=True, null=True)
    classB = models.ForeignKey(B, blank=True, null=True)

Когда я создаю объекты C, я гарантирую, что объект имеет ЛИБО отношение classA или classB.

Я ищу один набор запросов, который получает мне объекты C для конкретных значений fieldOfA или конкретных значений fieldOfB.

Я пробовал это, но это не удается (возвращает [], несмотря на наличие действительных результатов).

#Views - assume double underscore in the query
from django.db.models import Q
my_query = C.objects.filter(Q(classA _ _isnull = False, classA _ _fieldOfA = 'foo') | Q(classB _ _isnull = False, classB _ _fieldOfB = 'foo'))

Проблема, которую я вижу, это '|' это применяется. Два разных набора запросов для classA и classB работают нормально. В любом случае я мог бы применить один набор запросов, чтобы сделать эту работу? Или, что еще хуже, способ объединения отдельных наборов запросов.

2 ответа

Если вы можете быть уверены, что C имеет A или B, но никогда не оба, ваш isnull ограничения являются избыточными. Что произойдет, если вы запустите следующее?

C.objects.filter(Q(classA__fieldOfA = 'foo') | Q(classB__fieldOfB = 'foo'))

Если это все еще не работает, запустите manage.py shell и после выполнения вышеуказанного запроса (гарантируя, что settings.DEBUG является Trueпроверьте сгенерированный SQL для вышеупомянутого с

>>> from django.db import connection
>>> connection.queries()

Что ты видишь?

На самом деле, вы можете объединить QuerySetс таким же образом. Вот так:

C.objects.filter(classA__fieldOfA='foo') | C.objects.filter(classB__fieldOfB='foo')
Другие вопросы по тегам