Django - 使用Q跨越空关系的Queryset

时间:2009-07-10 16:52:30

标签: django django-queryset django-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关系。

我正在寻找一个查询集,它可以获取特定fieldOfA或特定fieldOfB值的C对象。

我尝试了这个,但它失败了(尽管有有效的结果,却返回[])。

#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 个答案:

答案 0 :(得分:2)

如果您可以确定C具有A或B但从不两者都有,则isnull约束是多余的。如果运行以下操作会发生什么?

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

如果仍然无法运行,请运行manage.py shell并在运行上述查询后(确保settings.DEBUGTrue,请使用

检查上面生成的SQL
>>> from django.db import connection
>>> connection.queries()

你看到了什么?

答案 1 :(得分:2)

实际上,可以以相同的方式组合QuerySet。像这样:

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