你怎么看这个例外? [英] How do you catch this exception?
问题描述
此代码在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
异常作为每个模型类的属性,以识别找不到的
对象的类,并允许您捕获特定的
cc 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 usesself.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屋!