我有一些模型的关系如下:
class Container(models.Model):
pass
class Child(models.Model):
container = models.ForeignKey(Container, related_name='children')
tag = models.CharField(max_length=40)
val = models.IntegerField()
我想过滤容器是否可以找到两个单独的 children
,其中一个tag
'foo'
个val
} [1,2,3]
和另一个tag
bar
val
[3,4,5]
。{/ p>
当我按以下方式过滤时:
print list(Container.filter(
Q(children__tag='foo', val__in=[1,2,3]) &
Q(children__tag='bar', val__in=[5,6,7]))
).distinct()
Django太聪明了。它会对每个Child
进行过滤,以确保它具有 tag
'foo'
和'bar'
以及中的值 [1,2,3]
和[5,6,7]
,其中包含以下SQL:
SELECT
COUNT(DISTINCT `app_container`.`id`)
FROM
`app_container`
INNER JOIN
`app_child` ON (`app_container`.`id` = `app_child`.`container_id`)
WHERE
app_child.tag = 'foo'
AND app_child.val in (1,2,3)
AND app_child.tag = 'bar'
AND app_child.val in (5,6,7)
我希望django做以下的事情来获得Container
与两个不同的孩子:
SELECT
COUNT(DISTINCT `app_container`.`id`)
FROM
`app_container`
LEFT JOIN
`app_child` c1 ON (`app_container`.`id` = `c1`.`container_id`)
LEFT JOIN
`app_child` c2 ON (`app_container`.`id` = `c1`.`container_id`)
WHERE
c1.tag = 'foo'
AND c1.val in (1,2,3)
AND c2.tag = 'bar'
AND c2.val in (5,6,7)
答案 0 :(得分:2)
如果内存服务,一种方法是链接过滤器调用:
Container.objects() \
.filter(children__tag='foo', children__val__in=[1,2,3]) \
.filter(children__tag='bar', children__val__in=[5,6,7]) \
.distinct()
一对多的filter
查找符合条件的单个相关对象,但两个链接的调用应该彼此独立。
答案 1 :(得分:0)
我提出了一个解决方案,但我不确定其他人是否更有效率:
print list(Container.filter(
Q(pk__in=Container.objects.filter(children__tag='foo', val__in=[1,2,3])) &
Q(pk__in=Container.objects.filter(children__tag='bar', val__in=[4,5,6]))
).distinct()