Django多对多过滤

时间:2015-02-12 16:27:45

标签: python django orm

假设以下一组模型:

class A(models.Model):
  pass

class B(models.Model):
  pass

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

通过链接上的某些条件过滤(这是较大应用程序链中的一部分)的方法,在天真的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产生正确的连接?

2 个答案:

答案 0 :(得分:2)

您应该通过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')

答案 1 :(得分:0)

您可以在单个查询中实现此目的。例如,假设您要仅在模型x中的字段B上过滤那些值大于50的记录,您可以执行以下操作:

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

您可以在related name lookups here

上阅读更多内容
相关问题