How do you catch this exception?

This code is in django / db / models / fields.py Does it create / define an exception?

class ReverseSingleRelatedObjectDescriptor(six.with_metaclass(RenameRelatedObjectDescriptorMethods)): # This class provides the functionality that makes the related-object # managers available as attributes on a model class, for fields that have # a single "remote" value, on the class that defines the related field. # In the example "choice.poll", the poll attribute is a # ReverseSingleRelatedObjectDescriptor instance. def __init__(self, field_with_rel): self.field = field_with_rel self.cache_name = self.field.get_cache_name() @cached_property def RelatedObjectDoesNotExist(self): # The exception can't be created at initialization time since the # related model might not be resolved yet; `rel.to` might still be # a string model reference. return type( str('RelatedObjectDoesNotExist'), (self.field.rel.to.DoesNotExist, AttributeError), {} ) 

This is in django / db / models / fields / related.py, it raises the above exception:

 def __get__(self, instance, instance_type=None): if instance is None: return self try: rel_obj = getattr(instance, self.cache_name) except AttributeError: val = self.field.get_local_related_value(instance) if None in val: rel_obj = None else: params = dict( (rh_field.attname, getattr(instance, lh_field.attname)) for lh_field, rh_field in self.field.related_fields) qs = self.get_queryset(instance=instance) extra_filter = self.field.get_extra_descriptor_filter(instance) if isinstance(extra_filter, dict): params.update(extra_filter) qs = qs.filter(**params) else: qs = qs.filter(extra_filter, **params) # Assuming the database enforces foreign keys, this won't fail. rel_obj = qs.get() if not self.field.rel.multiple: setattr(rel_obj, self.field.related.get_cache_name(), instance) setattr(instance, self.cache_name, rel_obj) if rel_obj is None and not self.field.null: raise self.RelatedObjectDoesNotExist( "%s has no %s." % (self.field.model.__name__, self.field.name) ) else: return rel_obj 

The problem is that this code:

  try: val = getattr(obj, attr_name) except related.ReverseSingleRelatedObjectDescriptor.RelatedObjectDoesNotExist: val = None # Does not catch the thrown exception 

isinstance (foo, related.FieldDoesNotExist) False except Exception as foo: Print type (foo) # Captures here, not higher

won't catch this exception

 >>>print type(foo) <class 'django.db.models.fields.related.RelatedObjectDoesNotExist'> 

and

 except related.RelatedObjectDoesNotExist: 

Raises AttributeError: 'module' object has no attribute 'RelatedObjectDoesNotExist'

 >>>isinstance(foo, related.ReverseSingleRelatedObjectDescriptor.RelatedObjectDoesNotExist) Traceback (most recent call last): File "<string>", line 1, in <fragment> TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types 

probably that's why.

+80
python django exception
Oct 09
source share
4 answers

If your sibling model is called Foo, you can simply do:

 except Foo.DoesNotExist: 

Django is amazing when not scared. RelatedObjectDoesNotExist is a property that returns a type that is dynamically evaluated at runtime. This type uses self.field.rel.to.DoesNotExist as a base class. According to the Django documentation:

ObjectDoesNotExist and DoNotExist

DoesNotExist exception

A DoNotExist exception occurs when an object is not found for the specified query parameters. Django provides a DoNotExist exception as an attribute of each model class to define a class object that cannot be found, and so you can catch a specific model class with try / except .

This is the magic that makes this happen. After the model has been built, self.field.rel.to.DoesNotExist is a does-not-exist exception for this model.

+168
Oct 09 '14 at 5:12
source share

If you do not want to import the corresponding model class, you can:

 except MyModel.related_field.RelatedObjectDoesNotExist: 

or

 except my_model_instance._meta.model.related_field.RelatedObjectDoesNotExist: 

where related_field is the name of the field.

+19
Nov 17 '16 at 2:43
source share

To catch this exception in general, you can do

 from django.core.exceptions import ObjectDoesNotExist try: # Your code here except ObjectDoesNotExist: # Handle exception 
+9
Mar 15 '17 at 21:58
source share

Tdelaney's answer is great for regular code codes, 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() 
0
Dec 22 '17 at 20:13
source share



All Articles