Django ORM:构造查询,该查询将在多对多字段的最后位置的对象中的字段上查找匹配项

Posted

技术标签:

【中文标题】Django ORM:构造查询,该查询将在多对多字段的最后位置的对象中的字段上查找匹配项【英文标题】:Django ORM: construct query that would look for match on field in object at the last position of many to many field 【发布时间】:2019-06-20 15:50:14 【问题描述】:

我偶然发现了一些我自己无法弄清楚的事情 - 在过滤(在 Django ORM 中)查询时,我想查询满足条件的对象,多对多对象列表中最后一个对象的某些字段是相等的一些输入。听起来可能不是那么明显,所以下面我提供一个例子: 动物模型

class Animal(models.Model):
    name = models.TextField(null=True, blank=False)
    awards = models.ManyToManyField(Award, related_name='awards')

获奖模特

class Award(models.Model):
    name = models.TextField(null=False, blank=False)
    place = models.TextField(null=True, blank=True)
    date = models.DateTimeField(null=True)

    class Meta:
        ordering = ['date']

有了这些类,我想构造这样的查询:

Animal.objects.filter(awards__name__last='National Award')

因为Animal.objects.filter(awards__name='National Award') 通常返回(使用.values() 时)列表如下所示:

['name': u'National Award', 'place': u'capital', 'date': datetime.datetime(2018, 7, 13, 5, 2, 45, 23000), u'id': 1, 'name': u'International Award', 'place': u'capital', 'date': datetime.datetime(2018, 10, 1, 1, 1, 55, 79000), u'id': 2]

对于这样的对象,查询会省略它,因为“国家奖”不在列表的最后一个位置,但是如果这个对象会切换这些条目,那么这个查询会返回它,因为最后一个对象name 等于“国家奖”。我不想为此查询使用date 字段。

【问题讨论】:

什么是“最后一个位置”,Award最大 时间?除了列中的值之外,记录没有“固有顺序”:可以按任何可能的顺序检索记录,除非您在字段上对其进行排序。 是的,很抱歉,我忘记粘贴负责订购的代码。刚刚修好了。 【参考方案1】:

您应该能够注释上一个奖项的日期,然后根据该日期和奖项名称进行过滤:

from django.db.models import F, Max

animals = Animal.objects.annotate(
    last_award_date=Max('awards__date')
).filter(
    awards__date=F('last_award_date'), awards__name='National Award'
)

【讨论】:

以上是关于Django ORM:构造查询,该查询将在多对多字段的最后位置的对象中的字段上查找匹配项的主要内容,如果未能解决你的问题,请参考以下文章

django ORM中的RelatedManager(关联管理器)

Django - 查询列表中的任何项目在多对多字段中的任何对象

Django ORM - 通过模型查询多对多?

Python学习第135天(Django的ORM多对多查询)

Django 补充ORM多对多正向查询

Django ORM 查询更新反向多对多字段