Django 如何筛选两个不同的相关字段,并在一个查询中同时满足它们?

Django 如何筛选两个不同的相关字段,并在一个查询中同时满足它们?,django,django-models,Django,Django Models,我有一些模型的关系如下: 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() print list(Container.fil

我有一些模型的关系如下:

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()
print list(Container.filter( 
  Q(children__tag='foo', val__in=[1,2,3]) & 
  Q(children__tag='bar', val__in=[5,6,7]))
).distinct()
我想对容器进行筛选,以确定是否可以找到两个独立的
子项
,一个在
[1,2,3]
中带有
val
标签
,另一个在
[3,4,5]
中带有
val
标签

当我进行如下筛选时:

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()
print list(Container.filter( 
  Q(children__tag='foo', val__in=[1,2,3]) & 
  Q(children__tag='bar', val__in=[5,6,7]))
).distinct()
Django太聪明了。它过滤每个
子项
,以确保它同时具有一个
'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执行以下操作,以获得具有两个不同子级的
容器
s:

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)

如果内存可用,一种方法是链式筛选调用:

 Container.objects() \
    .filter(children__tag='foo', children__val__in=[1,2,3]) \
    .filter(children__tag='bar', children__val__in=[5,6,7]) \
    .distinct()

一对多上的
过滤器
查找满足条件的单个相关对象,但两个链接调用应相互独立。

如果内存可用,一种方法是链接过滤器调用:

 Container.objects() \
    .filter(children__tag='foo', children__val__in=[1,2,3]) \
    .filter(children__tag='bar', children__val__in=[5,6,7]) \
    .distinct()

一对多上的
过滤器
查找满足条件的单个相关对象,但两个链式调用应相互独立。

我想出了一个解决方案,但我不确定其他方法是否更有效:

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()

我提出了一个解决方案,但我不确定其他解决方案是否更有效:

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()