I have a simple blog app with the model “Post”. If I delete all the entries in the Post model I get an error when I try reference the first item in the post list ordered by date, which I did like this:
latest_post = Post.objects.order_by('-date_created')[0]
The error is: IndexError: list index out of range
As a fix, I now get the item like this:
all_posts = Post.objects.order_by('-date_created')
latest_post = ()
if (all_posts):
latest_post = all_posts[0]
This works if there are no items in my model “Post”, and no exception is thrown.
However to me this seems like too much code to do something fairly simple. I assume there is a better way to do this using the django QuerySet API, but can’t find anything in the documentation.
Any ideas?
EDIT: Strangely, this throws no error when there are no items in the Post model:
latest_post_list = Post.objects.all().order_by('-date_created')[1:10]
Nothing strange about that, it’s completely expected behavior. An empty list (or queryset specifically in this case) evaluates to False so you never index into the queryset. While if you try to index into an empty list (like you do with the first approach) it will throw an IndexError.
What you’ve written will work, but it’s not the best imo. A better way to write this would be like so
This is a more pythonic way of writing it and is easier to read and understand what you’re trying to do.
Or even better
Notice in this second example that it uses the latest() queryset method. Also note that the argument is simply the fieldname and not -fieldname. Also you can even specify in your models Meta class
get_latest_by = 'date_created'and then the line simply becomeslatest_post = Post.objects.latest()without even needing to specify the fieldname argument