Django Manytomy模型查询集联盟

2024-09-27 00:15:31 发布

您现在位置:Python中文网/ 问答频道 /正文

以下是一个基本的多对多关系模型:

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实例:

^{pr2}$

现在,我想获得与所有构造的MainModel对象相关联的所有ManyToManyModel的查询集。也许有更好的方法可以做到这一点,但是这个例子使用了union(django1.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在它的查询集中包含四个条目,但是让我们筛选出一个我关心的条目,例如,这个查询应该只返回带有name='Number 1'ManyToManyModel

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创建的查询集的行为不一样?在


Tags: to实例namein模型refgetmodels
1条回答
网友
1楼 · 发布于 2024-09-27 00:15:31

执行union后无法进行筛选。如前所述in the documentation

... only LIMIT, OFFSET, COUNT(*), and ORDER BY (i.e. slicing, count(), and order_by()) are allowed on the resulting QuerySet. Further, databases place restrictions on what operations are allowed in the combined queries. For example, most databases don’t allow LIMIT or OFFSET in the combined queries.

在您的情况下,您实际上可以通过以下方式获得所需的对象:

m2m_union.order_by('name').first()

但当然,这不是你想要的,在进行联合之前,你需要过滤所需的字段。在

相关问题 更多 >

    热门问题