你怎么看这个例外? [英] How do you catch this exception?

查看:177
本文介绍了你怎么看这个例外?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  class ReverseSingleRelatedObjectDescriptor six.with_metaclass(RenameRelatedObjectDescriptorMethods)):
#此类提供使相关对象
#管理器作为模型类的属性可用的功能,对于
#一个单个远程值,定义相关字段的类。
#在示例choice.poll中,poll属性是
#ReverseSingleRelatedObjectDescriptor实例。
def __init __(self,field_with_rel):
self.field = field_with_rel
self.cache_name = self.field.get_cache_name()

@cached_property
def RelatedObjectDoesNotExist(self):
#在初始化时不能创建异常,因为
#相关模型可能尚未解决; `rel.to`可能仍然是
#一个字符串模型引用。
返回类型(
str('RelatedObjectDoesNotExist'),
(self.field.rel.to.DoesNotExist,AttributeError),
{}

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

  def __get __(self,instance,instance_type = None):
如果实例为None:
return self
try:
rel_obj = getattr(instance,self.cache_name)
除了AttributeError:
val = self.field.get_local_related_value(实例)
如果在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)
如果isinstance(extra_filter,dict):
params.update(extra_filter)
qs = qs.filter(** params)
else:
qs = qs。 filter(extra_filter,** params)
#假设数据库强制执行外键,这不会失败。
rel_obj = qs.get()
如果不是self.field.rel.multiple:
setattr(rel_obj,self.field.related.get_cache_name(),instance)
setattr (实例,self.cache_name,rel_obj)
如果rel_obj是None而不是self.field.null:
raise self.RelatedObjectDoesNotExist(
%s没有%s。% .field.model .__ name__,self.field.name)

else:
return rel_obj

问题是这个代码:

  try:
val = getattr obj,attr_name)
except related.ReverseSingleRelatedObjectDescriptor.RelatedObjectDoesNotExist:
val = None#不捕获抛出的异常

isinstance(foo,related.FieldDoesNotExist)
False
除了作为foo的异常:
打印类型(foo)#捕获这里,不在



将不会捕获该异常

 >>>>>打印类型(foo)
< class'django.db.models.fields.related.RelatedObjectDoesNotExist >

  except related.RelatedObjectDoesNotExist:

引发 AttributeError:'模块'object has no attribute'RelatedObjectDoesNotExist'

 >>> isinstance(foo,related .ReverseSingleRelatedObjectDescriptor.RelatedObjectDoesNotExist)
追溯(最近的最后一次调用):
文件< string>,第1行,< fragment>
TypeError:isinstance()arg 2必须是类和类型的类,类型或元组

这可能是为什么。

解决方案

如果你的相关模型叫做Foo,你可以做:

  Foo.DoesNotExist除外:



Django是惊人的,当它不可怕。 RelatedObjectDoesNotExist 是一个返回在运行时动态计算出来的类型的属性。该类型使用 self.field.rel.to.DoesNotExist 作为基类。根据Django文档:


ObjectDoesNotExist和DoesNotExist



异常 DoesNotExist



当查询的给定参数找不到
的对象时,引发了 DoesNotExist 异常。 Django提供一个 DoesNotExist
异常作为每个模型类的属性,以识别找不到的
对象的类,并允许您捕获特定的
c c c c c blockquote>

这是使这种情况发生的魔法。一旦模型建立起来, self.field.rel.to.DoesNotExist 是该模型不存在的异常。


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.

这篇关于你怎么看这个例外?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆