Django 多对多过滤

Django Many-To-Many filtering

假设以下一组模型:

class A(models.Model):
  pass

class B(models.Model):
  pass

class M2M(models.Model):
  a = models.ForeignKey(A)
  b = models.ForeignKey(B)

通过链接上的某些条件 filter(这是一个更大应用程序链中的一部分)的一种方法,在天真的 Django ORM 中是这样做的:

def fun():
  as = A.objects.filter("some complex queryset") 

  m2ms = M2M.objects.filter("some complex B-dependent QS")

  return as.filter(id__in=[m.a_id for m in m2ms])  

但显然这会产生一个相当糟糕的查询 "id__in",并且显然会作为两个查询执行。

是否有更好的方法让 Django 生成正确的连接?

您可以在单个查询中实现此目的。例如,假设您只想过滤模型 B 中字段 x 的值大于 50 的那些记录,您可以这样做:

A.objects.filter("some-filter-criteria", m2m__b__x__gt=50)

您可以在 related name lookups here

上阅读更多内容

您应该通过 M2M 显式声明从 A 到 B 的多对多字段。

class A(models.Model):
  bs = models.ManyToManyField('B', through='M2M')

现在你可以简单地做:

A.objects.filter(condition_on_A='foo').filter(b__condition_on_b='bar')