这是一个基本的多对多关系模型:
from django.db import models
class ManyToManyModel(models.Model):
name = models.CharField(max_length=50)
class MainModel(models.Model):
name = models.CharField(max_length=50)
many_to_many_ref = models.ManyToManyField(ManyToManyModel)
我按如下方式创建这些模型的实例,将ManyToManyModel
个实例绑定到MainModel
个实例:
from app1.models import ManyToManyModel, MainModel
m2m1 = ManyToManyModel(name='Number 1')
m2m1.save()
m2m2 = ManyToManyModel(name='Number 2')
m2m2.save()
m2m3 = ManyToManyModel(name='Number 3')
m2m3.save()
m2m4 = ManyToManyModel(name='Number 4')
m2m4.save()
mm1 = MainModel(name='Main 1')
mm1.save()
mm1.many_to_many_ref.add(m2m1)
mm1.save()
mm2 = MainModel(name='Main 2')
mm2.save()
mm2.many_to_many_ref.add(m2m1)
mm2.many_to_many_ref.add(m2m2)
mm2.many_to_many_ref.add(m2m3)
mm2.save()
mm3 = MainModel(name='Main 3')
mm3.save()
mm3.many_to_many_ref.add(m2m4)
mm3.save()
现在,我希望得到一个与所有ManyToManyModel
个对象关联的所有MainModel
的Queryset。可能有更好的方法来执行此操作,但此示例使用union
(django 1.11中的新增内容):
for mm in MainModel.objects.all():
try:
m2m_union = m2m_union.union(mm.many_to_many_ref.all())
except NameError:
m2m_union = mm.many_to_many_ref.all()
现在,m2m_union
在其QuerySet中包含四个条目,但让我们过滤掉我关心的一个条目,例如此查询只应返回ManyToManyModel
name='Number 1'
:
m2m_union.get(name__endswith='1')
这会返回以下错误:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File ".../lib/python3.6/site-packages/django/db/models/query.py", line 384, in get
(self.model._meta.object_name, num)
app1.models.MultipleObjectsReturned: get() returned more than one ManyToManyModel -- it returned 4!
但是,如果我直接查询ManyToManyModel
个实例并尝试以这种方式获取对象,则可行:
ManyToManyModel.objects.all().get(name__endswith='1')
为什么迭代union
创建的QuerySet行为不一样?
答案 0 :(得分:1)
执行union
后,您无法进行过滤。如上所述in the documentation:
...只有LIMIT,OFFSET,COUNT(*)和ORDER BY(即切片,count(), 在得到的QuerySet上允许使用order_by())。进一步, 数据库限制了允许的操作 合并查询。例如,大多数数据库不允许LIMIT或 组合查询中的OFFSET。
在您的情况下,您实际上可以获得所需的对象:
m2m_union.order_by('name').first()
但当然,这不是你想要的,你会在结合前过滤所需的字段。