369👍
If your related model is called Foo you can just do:
except Foo.DoesNotExist:
Django is amazing when it’s not terrifying. RelatedObjectDoesNotExist
is a property that returns a type that is figured out dynamically at runtime. That type uses self.field.rel.to.DoesNotExist
as a base class.
According to Django documentation:
DoesNotExist
exception Model.DoesNotExist
This exception is raised by the ORM when an expected object is not
found. For example,QuerySet.get()
will raise it when no object
is found for the given lookups.Django provides a
DoesNotExist
exception as an attribute of
each model class to identify the class of object that could not be
found, allowing you to catch exceptions for a particular model class.The exception is a subclass of
django.core.exceptions.ObjectDoesNotExist
.
This is the magic that makes that happen. Once the model has been built up, self.field.rel.to.DoesNotExist
is the does-not-exist exception for that model.
74👍
If you don’t want to import the related model class, you can:
except MyModel.related_field.RelatedObjectDoesNotExist:
or
except my_model_instance._meta.model.related_field.RelatedObjectDoesNotExist:
where related_field
is the field name.
- [Django]-Django manage.py runserver invalid syntax
- [Django]-Resource temporarily unavailable using uwsgi + nginx
- [Django]-Extend base.html problem
60👍
Let’s say we have the following models:
class MainModel(Model):
pass
class RelatedModel(Model):
main = OneToOneField(MainModel, null=True, related_name="related")
You can get a RelatedObjectDoesNotExist
exception with MainModel().related
.
You have three options for catching this exception, which you can find by looking at .__class__.__mro__
of the exception:
MainModel.related.RelatedObjectDoesNotExist
RelatedModel.DoesNotExist
django.core.exceptions.ObjectDoesNotExist
MainModel.related.RelatedObjectDoesNotExist
RelatedObjectDoesNotExist
is what the question is looking for, but is specific to a nullable OneToOneField
:
try:
# Your code here
except MainModel.related.RelatedObjectDoesNotExist:
# Handle exception
RelatedModel.DoesNotExist
Model.DoesNotExist
is the parent class of RelatedObjectDoesNotExist
. To catch it requires you to be able to import the model in question, but is a more generically useful code pattern.
try:
# Your code here
except OtherModel.DoesNotExist:
# Handle exception
django.core.exceptions.ObjectDoesNotExist
ObjectDoesNotExist
is the parent class of Model.DoesNotExist
. This will catch this exception for any model, which is helpful if you don’t know what model will raise the exception:
from django.core.exceptions import ObjectDoesNotExist
try:
# Your code here
except ObjectDoesNotExist:
# Handle exception
- [Django]-Django custom field validator vs. clean
- [Django]-Python (and Django) best import practices
- [Django]-Django. A good tutorial for Class Based Views
12👍
The RelatedObjectDoesNotExist
exception is created dynamically at runtime. Here is the relevant code snippet for the ForwardManyToOneDescriptor
and ReverseOneToOneDescriptor
descriptors:
@cached_property
def RelatedObjectDoesNotExist(self):
# The exception can't be created at initialization time since the
# related model might not be resolved yet; `self.field.model` might
# still be a string model reference.
return type(
'RelatedObjectDoesNotExist',
(self.field.remote_field.model.DoesNotExist, AttributeError),
{}
)
So the exception inherits from <model name>.DoesNotExist
and AttributeError
. In fact, the complete MRO for this exception type is:
[<class 'django.db.models.fields.related_descriptors.RelatedObjectDoesNotExist'>,
<class '<model module path>.DoesNotExist'>,
<class 'django.core.exceptions.ObjectDoesNotExist'>,
<class 'AttributeError'>,
<class 'Exception'>,
<class 'BaseException'>,
<class 'object'>]
The basic takeaway is you can catch <model name>.DoesNotExist
, ObjectDoesNotExist
(import from django.core.exceptions
) or AttributeError
, whatever makes the most sense in your context.
- [Django]-Problems extend change_form.html in django admin
- [Django]-Why is logged_out.html not overriding in django registration?
- [Django]-Create a field whose value is a calculation of other fields' values
11👍
Little bit late but helpful for others.
2 ways to handle this.
1st :
When we need to catch exception
>>> from django.core.exceptions import ObjectDoesNotExist >>> try: >>> p2.restaurant >>> except ObjectDoesNotExist: >>> print("There is no restaurant here.") There is no restaurant here.
2nd:
When don’t want to handle exception
>>> hasattr(p2, 'restaurant') False
- [Django]-Switching to PostgreSQL fails loading datadump
- [Django]-Combining Django F, Value and a dict to annotate a queryset
- [Django]-Django-nonrel + Django-registration problem: unexpected keyword argument 'uidb36' when resetting password
3👍
tdelaney’s answer is great for regular code paths, but if you need to know how to catch this exception in tests:
from django.core.exceptions import ObjectDoesNotExist
...
def testCompanyRequired(self):
with self.assertRaises(ObjectDoesNotExist):
employee = Employee.objects.create()
- [Django]-Stack trace from manage.py runserver not appearing
- [Django]-'pip' is not recognized as an internal or external command
- [Django]-Django 1.8 KeyError: 'manager' on relationship