how to catch the MultipleObjectsReturned error in django
Question:
Is it possible to catch the MultipleObjectsReturned
error in Django?
I do a searchquery and if there are more than one objects I want that the first in the list will be taken so I tried this:
try:
Location.objects.get(name='Paul')
except MultipleObjectsReturned:
Location.objects.get(name='Paul')[0]
However, it exists in the doc though
global variable MultipleObjectsReturned does not exist
Answers:
Use a filter:
Location.objects.filter(name='Paul').first()
Or import the exception:
from django.core.exceptions import MultipleObjectsReturned
...
try:
Location.objects.get(name='Paul')
except MultipleObjectsReturned:
Location.objects.filter(name='Paul').first()
This isn’t the best practice. You can technically do this without using exceptions. Did you intend to use Location
and Car
in this example?
You can do this:
Location.objects.filter(name='Paul').order_by('id').first()
I strongly suggest you read the Django QuerySet API reference.
https://docs.djangoproject.com/en/1.8/ref/models/querysets/
To answer your question about where the exception exists — you can always access these QuerySet exceptions on the model itself. E.g. Location.DoesNotExist
and Location.MultipleObjectsReturned
. You don’t need to import them if you already have the model imported.
This is more pythonic way to do it.
try:
Location.objects.get(name='Paul')
except Location.MultipleObjectsReturned:
Location.objects.filter(name='Paul')[0]
Actually, even if we use MyModel.objects.get_or_create(...)
, there is still chances for creation of multiple instances due to race conditions. So, when we have to use MyModel.objects.get
or MyModel.objects.get_or_create
, we still have to expect return of multiple objects.
To handle this:
from django.core.exceptions import MultipleObjectsReturned
try:
obj,is_created=MyModel.objects.get_or_create(....)
except MultipleObjectsReturned as e:
# handle the case as you need here
pass
Use get when you know there is only one object that matches your query. If no items match the query, get() will raise a DoesNotExist exception. If multiple items matches the query, get() will raise a MultipleObjectsReturned exception. Use get() like this:
try:
one_entry = Entry.objects.get(blog=2000)
except Entry.DoesNotExist:
# query did not match to any item.
pass
except Entry.MultipleObjectsReturned:
# query matched multiple items.
pass
else:
# query matched to just one item
print(one_entry)
Is it possible to catch the MultipleObjectsReturned
error in Django?
I do a searchquery and if there are more than one objects I want that the first in the list will be taken so I tried this:
try:
Location.objects.get(name='Paul')
except MultipleObjectsReturned:
Location.objects.get(name='Paul')[0]
However, it exists in the doc though
global variable MultipleObjectsReturned does not exist
Use a filter:
Location.objects.filter(name='Paul').first()
Or import the exception:
from django.core.exceptions import MultipleObjectsReturned
...
try:
Location.objects.get(name='Paul')
except MultipleObjectsReturned:
Location.objects.filter(name='Paul').first()
This isn’t the best practice. You can technically do this without using exceptions. Did you intend to use Location
and Car
in this example?
You can do this:
Location.objects.filter(name='Paul').order_by('id').first()
I strongly suggest you read the Django QuerySet API reference.
https://docs.djangoproject.com/en/1.8/ref/models/querysets/
To answer your question about where the exception exists — you can always access these QuerySet exceptions on the model itself. E.g. Location.DoesNotExist
and Location.MultipleObjectsReturned
. You don’t need to import them if you already have the model imported.
This is more pythonic way to do it.
try:
Location.objects.get(name='Paul')
except Location.MultipleObjectsReturned:
Location.objects.filter(name='Paul')[0]
Actually, even if we use MyModel.objects.get_or_create(...)
, there is still chances for creation of multiple instances due to race conditions. So, when we have to use MyModel.objects.get
or MyModel.objects.get_or_create
, we still have to expect return of multiple objects.
To handle this:
from django.core.exceptions import MultipleObjectsReturned
try:
obj,is_created=MyModel.objects.get_or_create(....)
except MultipleObjectsReturned as e:
# handle the case as you need here
pass
Use get when you know there is only one object that matches your query. If no items match the query, get() will raise a DoesNotExist exception. If multiple items matches the query, get() will raise a MultipleObjectsReturned exception. Use get() like this:
try:
one_entry = Entry.objects.get(blog=2000)
except Entry.DoesNotExist:
# query did not match to any item.
pass
except Entry.MultipleObjectsReturned:
# query matched multiple items.
pass
else:
# query matched to just one item
print(one_entry)