The get_object_or_404 is a handy Django shortcut. It keeps my views shorter.
In my case however, I had the need to get the latest object. In my situation, I have surveys that can be asked more than one time to the same person. I want to fetch the most recent survey only.
get_object_or_404(Survey, patient_id=1234) #this could result in more than one object and may fail.
What I really want to do is something like this:
get_object_or_404(Survey, patient_id=1234, latest=True) #This does not work
..but alas Django doesn’t let me do that. A quick scan of the Django source code gave me a hint to build a custom function to handle my use case. Below is my utility called “get_latest_object_or_404″, which always gets the latest object and thus ensures that I always only fetch one object and said object is the newest. This of course requires that you have latest defined in your model’s Meta class. So here goes.
#!/usr/bin/env python # -*- coding: utf-8 -*- # vim: ai ts=4 sts=4 et sw=4 from django.http import Http404 from django.shortcuts import _get_queryset def get_latest_object_or_404(klass, *args, **kwargs): """ Uses get().latest() to return object, or raises a Http404 exception if the object does not exist. klass may be a Model, Manager, or QuerySet object. All other passed arguments and keyword arguments are used in the get() query. Note: Like with get(), an MultipleObjectsReturned will be raised if more than one object is found. """ queryset = _get_queryset(klass) try: return queryset.filter(*args, **kwargs).latest() except queryset.model.DoesNotExist: raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
I hope someone else finds this little contribution to the Django community useful. I think it should be added to the django.shortcuts library. Maybe I’ll propose that. Enjoy!