1

I want to get a list of max ids for a filter I have in Django

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

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

End result a queryset having only the latest objects by id for each name. How can I do that in Django?

Edit: I want multiple objects in the end result. Not just one object.

Edit1: Added __in. Once again I need only latest( as a result distinct) objects for each name.

Something like this.

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)

The above works. But I want a more concise way of doing it. Is it possible to do this in a single query/filter annotate combination?

4
  • latest you mean by time? if you have a creation time, just order by date and get the first result. Commented Sep 20, 2017 at 13:59
  • Latest by id is possible, but that will give me just one object. I want multiple objects in the end result based on the name. Commented Sep 20, 2017 at 14:01
  • so order_by id. Commented Sep 20, 2017 at 14:02
  • @Bestasttung I want multiple objects in the output. Sorting by id and taking the latest won't work. Commented Sep 20, 2017 at 14:05

2 Answers 2

1

you can try:

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)
Sign up to request clarification or add additional context in comments.

2 Comments

I just saw this. Is there a more efficient way of doing this?
unfortunately i don't know, how add annotate column to the filter, but if you find the solution it will good, by the way, it is not bad as it look
1

If you are using PostgreSQL you can do the following

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

MySQL is more complicated since is lacks a DISTINCT ON clause. Here is the raw query that is very hard to force Django to generate from ORM function calls:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.