In django a queryset is similar to a list but does not support negative indexing like a normal list. This makes it difficult to get the last element by traditional method.
Let us say we have a model like this.
This is a simple post model which have two fields “title” and “date”. If we want to get all the posts we can do something like this
This returns all the posts in the database. If we want to get the first post we can simply use
post = Post.objects.all() first_post = post
But if we try get last post like “post[-1]” we will get an error message like this
"Negative indexing is not supported." AssertionError: Negative indexing is not supported.
We can fix this by the following methods.
we can user order_by method to sort the dictionary in descending order and then get the first value from the queryset.
first_post = Post.objects.all().order_by('-pk')
we can also order by using any particular fields. I do not want any such field based ordering so i am simply using the pk field (primary key – this field will be available by default on all models)
pk will sort in ascending order
-pk will sort in descending order
2. last() method and first() method
we can also get the last value in the list by using the last() method.
last_post = Post.objects.all().last() last_post = Post.objects.last() last_post = Post.objects.filter(title='car').last()
This will return the last post from the queryset. Similarly we can get the first element from the list by using the first() method.
first_post = Post.objects.all().first() first_post = Post.objects.first() first_post = Post.objects.filter(title='car').first()
3. latest() method and earliest() method
The latest() method can also be used to get the last item from the queryset like this.
last_post = Post.objects.all().latest('pk') last_post = Post.objects.filter(title='cars').latest('pk')
You can use any key as an argument to the latest method like “lates(‘data’)” or “latest(‘post’)”.
In order to get the first element we can use the earliest() method. This will return the first element from the queryset.
first_post = Post.objects.all().earliest('pk') first_post = Post.objects.filter(title='cars').earliest('pk')
These methods will make your code looks cleaner instead of using index value to access the element form the queryset like “post”
It is preferred to use the “first()” and “last()” method as they dont require any keyword or arguments.
Happy coding !