A get_or_none()
function has been proposed, multiple times now. The rejection notice is feature creep, which you might or might not agree with. The functionality is present --with slightly different semantics-- in the first()
queryset method.
But first things first:
The manager throws World.DoesNotExist
, a specialized subclass of ObjectDoesNotExist
when a World
object was not found:
try:
personalProfile = World.objects.get(ID=personID)
except World.DoesNotExist:
pass
There's also get_object_or_404()
which raises a Http404
exception when the object was not found.
You can also roll your own get_or_none()
. A possible implementation could be:
def get_or_none(queryset, *args, **kwargs):
try:
return queryset.get(*args, **kwargs)
except ObjectDoesNotExist:
return None
Note that this still raises MultipleObjectsReturned
when more than one matching object is found. If you always want the first object regardless of any others, you can simplify using first()
, which returns None
when the queryset is empty:
def get_or_none(queryset, *args, **kwargs):
return queryset.filter(*args, **kwargs).first()
Note however, for this to work reliably, you need a proper order for objects, because in the presence of multiple objects first()
might be non-deterministic (it probably returns the first object from the database index used to filter the query and neither indexes not the underlying tables need be sorted or even have a repeatable order).
Use both, however, only when the use of the object to retrieve is strictly optional for the further program flow. When failure to retrieve an object is an error, use get_object_or_404()
. When an object should be created when it does not exist, use get_or_create()
. In those cases, both are better suited to simplify program flow.