Python 你如何捕捉这个异常?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26270042/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you catch this exception?
提问by boatcoder
This code is in django/db/models/fields.py It creates/defines an exception?
这段代码在 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),
{}
)
This is in django/db/models/fields/related.py it raises the said exception above:
这是在 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
The problem is that this code:
问题是这段代码:
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
won't catch that exception
不会捕捉到那个异常
>>>print type(foo)
<class 'django.db.models.fields.related.RelatedObjectDoesNotExist'>
>>>isinstance(foo, related.FieldDoesNotExist)
False
and
和
except related.RelatedObjectDoesNotExist:
Raises an AttributeError: 'module' object has no attribute '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
which is probably why.
这可能是为什么。
采纳答案by tdelaney
If your related model is called Foo you can just do:
如果你的相关模型被称为 Foo 你可以这样做:
except Foo.DoesNotExist:
Django is amazing when its not terrifying. RelatedObjectDoesNotExistis a property that returns a type that is figured out dynamically at runtime. That type uses self.field.rel.to.DoesNotExistas a base class. According to Django documentation:
Django 在它不可怕的时候是惊人的。RelatedObjectDoesNotExist是返回在运行时动态计算出的类型的属性。该类型self.field.rel.to.DoesNotExist用作基类。根据 Django 文档:
ObjectDoesNotExist and DoesNotExist
exception DoesNotExist
The DoesNotExistexception is raised when an object is not found for the given parameters of a query. Django provides a DoesNotExistexception 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.
ObjectDoesNotExist 和DoesNotExist
异常不存在
该DoesNotExist时未找到查询的给定参数的对象异常。Django 提供了一个DoesNotExist异常作为每个模型类的属性,以标识无法找到的对象的类,并允许您使用
try/except捕获特定的模型类。
This is the magic that makes that happen. Once the model has been built up, self.field.rel.to.DoesNotExistis the does-not-exist exception for that model.
这就是让这一切发生的魔法。一旦模型建立起来,self.field.rel.to.DoesNotExist就是那个模型不存在的例外。
回答by Fush
If you don't want to import the related model class, you can:
如果不想导入相关的模型类,可以:
except MyModel.related_field.RelatedObjectDoesNotExist:
or
或者
except my_model_instance._meta.model.related_field.RelatedObjectDoesNotExist:
where related_fieldis the field name.
related_field字段名在哪里。
回答by Zags
To catch this exception in general, you can do
要在一般情况下捕获此异常,您可以执行
from django.core.exceptions import ObjectDoesNotExist
try:
# Your code here
except ObjectDoesNotExist:
# Handle exception
回答by LisaD
tdelaney's answer is great for regular code paths, but if you need to know how to catch this exception in tests:
tdelaney 的答案非常适合常规代码路径,但如果您需要知道如何在测试中捕获此异常:
from django.core.exceptions import ObjectDoesNotExist
...
def testCompanyRequired(self):
with self.assertRaises(ObjectDoesNotExist):
employee = Employee.objects.create()
回答by C S
The RelatedObjectDoesNotExistexception is created dynamically at runtime. Here is the relevant code snippet for the ForwardManyToOneDescriptorand ReverseOneToOneDescriptordescriptors:
将RelatedObjectDoesNotExist在运行时动态创建的例外。以下是ForwardManyToOneDescriptor和ReverseOneToOneDescriptor描述符的相关代码片段:
@cached_property
def RelatedObjectDoesNotExist(self):
# The exception can't be created at initialization time since the
# related model might not be resolved yet; `self.field.model` might
# still be a string model reference.
return type(
'RelatedObjectDoesNotExist',
(self.field.remote_field.model.DoesNotExist, AttributeError),
{}
)
So the exception inherits from <model name>.DoesNotExistand AttributeError. In fact, the complete MRO for this exception type is:
所以异常继承自<model name>.DoesNotExistand AttributeError。事实上,这种异常类型的完整 MRO 是:
[<class 'django.db.models.fields.related_descriptors.RelatedObjectDoesNotExist'>,
<class '<model module path>.DoesNotExist'>,
<class 'django.core.exceptions.ObjectDoesNotExist'>,
<class 'AttributeError'>,
<class 'Exception'>,
<class 'BaseException'>,
<class 'object'>]
The basic takeaway is you can catch <model name>.DoesNotExist, ObjectDoesNotExist(import from django.core.exceptions) or AttributeError, whatever makes the most sense in your context.
基本要点是您可以 catch <model name>.DoesNotExist, ObjectDoesNotExist(import from django.core.exceptions) or AttributeError,任何在您的上下文中最有意义的东西。
回答by Muhammad Faizan Fareed
Little bit late but helpful for others.
有点晚,但对其他人有帮助。
2 ways to handle this.
2种方法来处理这个。
1st :
第一:
When we need to catch exception
当我们需要捕获异常时
>>> from django.core.exceptions import ObjectDoesNotExist >>> try: >>> p2.restaurant >>> except ObjectDoesNotExist: >>> print("There is no restaurant here.") There is no restaurant here.
>>> from django.core.exceptions import ObjectDoesNotExist >>> try: >>> p2.restaurant >>> except ObjectDoesNotExist: >>> print("There is no restaurant here.") There is no restaurant here.
2nd:When don't want to handle exception
第二:当不想处理异常时
>>> hasattr(p2, 'restaurant') False
>>> hasattr(p2, 'restaurant') False

