Django queryset获取过滤器的最大ID

时间:2017-09-20 13:57:47

标签: django django-queryset

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

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

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

最终结果是每个名称只有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)

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

3 个答案:

答案 0 :(得分:1)

你可以尝试:

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)

答案 1 :(得分: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 :(得分:-1)

现在问题已经更新,让我们看看我们是否可以做到这一点:

qs = Foo.objects.filter(
    id__in=SubQuery(
        Foo.objects.filter(
            name__in=['foo','koo','too']
        ).order_by('-id').first().values('id')
    )
)

(需要Django 1.11 +)