32

given a standard model (called Image) with an autoset 'id', how do I get the max id?

So far I've tried:

max_id = Image.objects.all().aggregate(Max('id'))

but I get a 'id__max' Key error.

Trying

max_id = Image.objects.order_by('id')[0].id

gives a 'argument 2 to map() must support iteration' exception

Any help?

pistacchio
  • 56,889
  • 107
  • 278
  • 420
  • Why do you want the max id? Do you want the last thing loaded? The thing with the largest date? The ID's are random numbers, they don't mean much and there's no guarantee that max(id) has any useful properties at all. What are you *really* trying to do? – S.Lott May 21 '10 at 18:21
  • http://stackoverflow.com/questions/2087670/how-to-aggregate-over-a-single-queryset-in-django – Daniel DiPaolo May 21 '10 at 19:06

7 Answers7

74

In current version of django (1.4) it is even more readable

Image.objects.latest('id').id

Raz
  • 7,508
  • 4
  • 27
  • 25
  • 3
    If there are no objects this will throw a Image.DoesNotExist exception – Necrolyte2 Mar 07 '13 at 16:38
  • 4
    Yes and previous answer will raise IndexError in this case. – Raz Mar 08 '13 at 18:10
  • 1
    It works on any field. Look at the source. It is just syntax sugar for `QuerySet.order_by('-%s' % field)[:1].get()`. – Raz Apr 03 '14 at 07:04
  • 1
    Only works if there is at least one object, try catch would be appropriate along with this. – Mutant Dec 05 '14 at 15:19
  • To save other people time, this is how you would do it: `from django.db import models max_id = None try: max_id = Image.objects.latest('id').id except models.DoesNotExist: pass` – theQuestionMan Oct 16 '20 at 01:05
49

Just order by reverse id, and take the top one.

Image.objects.all().order_by("-id")[0]
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • 2
    Isn't this going to evaluate the queryset and perform object construction? `Image.objects.values('id').aggregate(min_id=Min('id'))` would produce a single-key dict containing the min_id. Maybe this wasn't possible 10 years ago. – Ivan Jan 10 '20 at 20:20
  • django keeps an index on the id column by default so the aggregate will be much slower esp. for large tables. Daniel's answer performs best although it would be even better with a .values('id') – Tom McClure Jan 30 '23 at 20:08
19

I know this already has a right answer but here it's another way of doing it:

prev = Image.objects.last()

This gives you the last object.

patricia
  • 1,075
  • 1
  • 16
  • 44
  • I prefer `.last()` over `.latest()` as **`.last()` will not raise an exception if the queryset is empty**. For other differences between the two, see [this answer](https://stackoverflow.com/a/73298176/11875147). – Jakub Holan May 19 '23 at 20:42
4

This worked for me

[model].objects.last().id

Image.objects.last().id
Uday Kiran
  • 659
  • 8
  • 8
3

Your logic is right, this will return the max id

res = Image.objects.filter().aggregate(max_id=Max('pk'))
res.get('max_id')
Mario César
  • 3,699
  • 2
  • 27
  • 42
3

this also work perfectly:

max_id = Image.objects.values('id').order_by('-id').first()
-2

Latest object without catching exception and using django orm:

Image.objects.filter().order_by('id').first()

  • 1
    First would return the smallest id, wouldn't it? Shouldn't you use last()? or '-' with id to give descending? – TzurEl Nov 07 '18 at 14:17