How do you catch this exception?

This code is in django/db/models/fields.py It creates/defines 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 said exception above:

    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) # Catches here, not above

won't catch that exception

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

and

    except related.RelatedObjectDoesNotExist:

Raises an 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

which is probably why.

If your related model is called Foo you can just do:

    except Foo.DoesNotExist:

Django is amazing when its 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:

ObjectDoesNotExist and DoesNotExist

exception DoesNotExist

The DoesNotExist exception is raised when an object is not found for the given parameters of a query. Django provides a DoesNotExist exception as an attribute of each model class to identify the class of object that could not be found and to allow you to catch a particular model class with try/except.

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.

From: stackoverflow.com/q/26270042