小编典典

你如何捕捉到这个异常?

all

这段代码在 django/db/models/fields.py 它创建/定义了一个异常?

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),
            {}
        )

这是在 django/db/models/fields/related.py 它引发了上述异常:

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

问题是这段代码:

    try:
        val = getattr(obj, attr_name)
    except related.ReverseSingleRelatedObjectDescriptor.RelatedObjectDoesNotExist:
        val = None  # Does not catch the thrown exception
    except Exception as foo:
        print type(foo)  # Catches here, not above

不会捕获该异常

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

except related.RelatedObjectDoesNotExist:

引发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

这可能就是为什么。


阅读 96

收藏
2022-07-17

共1个答案

小编典典

如果您的相关模型称为 Foo 您可以这样做:

except Foo.DoesNotExist:

当 Django
不可怕时,它就很棒。RelatedObjectDoesNotExist是一个属性,它返回在运行时动态计算出的类型。该类型self.field.rel.to.DoesNotExist用作基类。

根据 Django 文档:

不存在

异常 模型.DoesNotExist

当未找到预期对象时,ORM 会引发此异常。例如, QuerySet.get() 当没有为给定的查找找到对象时将引发它。

Django 提供了一个 DoesNotExist 异常作为每个模型类的属性来识别找不到的对象的类,允许您捕获特定模型类的异常。

例外是 的子类 django.core.exceptions.ObjectDoesNotExist

这就是使这一切发生的魔力。一旦建立模型,self.field.rel.to.DoesNotExist该模型就不存在异常。

2022-07-17