Get last record in a queryset

DjangoDjango Queryset

Django Problem Overview


How can I retrieve the last record in a certain queryset?

Django Solutions


Solution 1 - Django

Django Doc:

> latest(field_name=None) returns the latest object in the table, by date, using the field_name provided as the date field. >
> This example returns the latest Entry in the table, according to the > pub_date field: > > Entry.objects.latest('pub_date')

Solution 2 - Django

EDIT : You now have to use Entry.objects.latest('pub_date')


You could simply do something like this, using reverse():

queryset.reverse()[0]

Also, beware this warning from the Django documentation:

> ... note that reverse() should > generally only be called on a QuerySet > which has a defined ordering (e.g., > when querying against a model which > defines a default ordering, or when > using order_by()). If no such ordering > is defined for a given QuerySet, > calling reverse() on it has no real > effect (the ordering was undefined > prior to calling reverse(), and will > remain undefined afterward).

Solution 3 - Django

The simplest way to do it is:

books.objects.all().last()

You also use this to get the first entry like so:

books.objects.all().first()

Solution 4 - Django

To get First object:

ModelName.objects.first()

To get last objects:

ModelName.objects.last()

You can use filter

ModelName.objects.filter(name='simple').first()

This works for me.

Solution 5 - Django

Django >= 1.6

Added QuerySet methods first() and last() which are convenience methods returning the first or last object matching the filters. Returns None if there are no objects matching.

Solution 6 - Django

When the queryset is already exhausted, you may do this to avoid another db hint -

last = queryset[len(queryset) - 1] if queryset else None

Don't use try...except....
Django doesn't throw IndexError in this case.
It throws AssertionError or ProgrammingError(when you run python with -O option)

Solution 7 - Django

You can use Model.objects.last() or Model.objects.first(). If no ordering is defined then the queryset is ordered based on the primary key. If you want ordering behaviour queryset then you can refer to the last two points.

If you are thinking to do this, Model.objects.all().last() to retrieve last and Model.objects.all().first() to retrieve first element in a queryset or using filters without a second thought. Then see some caveats below.

The important part to note here is that if you haven't included any ordering in your model the data can be in any order and you will have a random last or first element which was not expected.

Eg. Let's say you have a model named Model1 which has 2 columns id and item_count with 10 rows having id 1 to 10.[There's no ordering defined]

If you fetch Model.objects.all().last() like this, You can get any element from the list of 10 elements. Yes, It is random as there is no default ordering.

So what can be done?

  1. You can define ordering based on any field or fields on your model. It has performance issues as well, Please check that also. Ref: Here
  2. OR you can use order_by while fetching. Like this: Model.objects.order_by('item_count').last()

Solution 8 - Django

If using django 1.6 and up, its much easier now as the new api been introduced -

Model.object.earliest()

It will give latest() with reverse direction.

p.s. - I know its old question, I posting as if going forward someone land on this question, they get to know this new feature and not end up using old method.

Solution 9 - Django

In a Django template I had to do something like this to get it to work with a reverse queryset:

thread.forumpost_set.all.last

Hope this helps someone looking around on this topic.

Solution 10 - Django

MyModel.objects.order_by('-id')[:1]

Solution 11 - Django

If you use ids with your models, this is the way to go to get the latest one from a qs.

obj = Foo.objects.latest('id')

Solution 12 - Django

The simplest way, without having to worry about the current ordering, is to convert the QuerySet to a list so that you can use Python's normal negative indexing. Like so:

list(User.objects.all())[-1]

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionStephen View Question on Stackoverflow
Solution 1 - DjangoAsinoxView Answer on Stackoverflow
Solution 2 - DjangojujuleView Answer on Stackoverflow
Solution 3 - Djangohaky_nashView Answer on Stackoverflow
Solution 4 - DjangoRavi KumarView Answer on Stackoverflow
Solution 5 - DjangopanchicoreView Answer on Stackoverflow
Solution 6 - Djangojifeng.yinView Answer on Stackoverflow
Solution 7 - DjangoRoshan DawandeView Answer on Stackoverflow
Solution 8 - DjangoMutantView Answer on Stackoverflow
Solution 9 - DjangoHarlinView Answer on Stackoverflow
Solution 10 - DjangoEILYAView Answer on Stackoverflow
Solution 11 - DjangoDavid LoudaView Answer on Stackoverflow
Solution 12 - DjangoJosh OurismanView Answer on Stackoverflow