【问题标题】:Django queryset get max id's for a filterDjango 查询集获取过滤器的最大 ID
【发布时间】:2018-03-01 15:13:51
【问题描述】:

我想获取我在 Django 中的过滤器的最大 ID 列表

class Foo(models.Model):
   name = models.CharField()
   poo = models.CharField() 

Foo.objects.filter(name__in=['foo','koo','too']).latest_by_id()

最终结果是一个查询集,每个名称只有最新的 objects(按 id)。如何在 Django 中做到这一点?

编辑:我希望最终结果中有多个对象。不只是一个对象。

Edit1:添加了 __in。再一次,我只需要每个名称的最新(因此是不同的)对象。

类似的东西。

my_id_list = [Foo.objects.filter(name=name).latest('id').id for name in ['foo','koo','too']]
Foo.objects.filter(id__in=my_id_list)

以上工作。但我想要一种更简洁的方法。是否可以在单个查询/过滤器注释组合中执行此操作?

【问题讨论】:

  • 最新的你是指时间吗?如果您有创建时间,只需按日期排序并获得第一个结果。
  • 最新的 id 是可能的,但这只会给我一个对象。我想要基于名称的最终结果中的多个对象。
  • so order_by id.
  • @Bestasttung 我想要输出中有多个对象。按 id 排序并获取最新的将不起作用。

标签: django django-queryset


【解决方案1】:

如果您使用的是 PostgreSQL,您可以执行以下操作

Foo.objects.order_by('name', '-id').distinct('name')

MySQL 更复杂,因为它缺少DISTINCT ON 子句。这是很难强制 Django 从 ORM 函数调用生成的原始查询:

Foo.objects.raw("""
    SELECT 
        *
    FROM
        `foo`
    GROUP BY `foo`.`name`
    ORDER BY `foo`.`name` ASC , `foo`.`id` DESC
""")

【讨论】:

    【解决方案2】:

    你可以试试:

    qs = Foo.objects.filter(name__in=['foo','koo','too'])
    # Get list of max == last pk for your filter objects
    max_pks = qs.annotate(mpk=Max('pk')).order_by().values_list('mpk', flat=True)
    # after it filter your queryset by last pk
    result = qs.filter(pk__in=max_pks)
    

    【讨论】:

    • 我刚看到这个。有没有更有效的方法来做到这一点?
    • 不幸的是,我不知道如何将annotate 列添加到过滤器中,但是如果您找到解决方案,它会很好,顺便说一下,它看起来还不错
    猜你喜欢
    • 2018-09-26
    • 2015-12-08
    • 2019-07-29
    • 1970-01-01
    • 2018-05-12
    • 1970-01-01
    • 2014-03-10
    • 2019-02-09
    • 2014-06-12
    相关资源
    最近更新 更多