Dieser Code befindet sich in django / db / models / fields.py. Erstellt / definiert eine Ausnahme?
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),
{}
)
Dies ist in django / db / models / fields / related.py die oben genannte Ausnahme:
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
Das Problem ist, dass dieser 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
wird diese Ausnahme nicht fangen
>>>print type(foo)
<class 'django.db.models.fields.related.RelatedObjectDoesNotExist'>
>>>isinstance(foo, related.FieldDoesNotExist)
False
und
except related.RelatedObjectDoesNotExist:
Erhöht eine 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
Das ist wahrscheinlich der Grund.
related
?AttributeError
anstelle vonrelated.ReverseSingleRelatedObjectDescriptor.RelatedObjectDoesNotExist
Antworten:
Wenn Ihr verwandtes Modell Foo heißt, können Sie einfach Folgendes tun:
Django ist erstaunlich, wenn es nicht erschreckend ist.
RelatedObjectDoesNotExist
ist eine Eigenschaft, die einen Typ zurückgibt, der zur Laufzeit dynamisch ermittelt wird. Dieser Typ wirdself.field.rel.to.DoesNotExist
als Basisklasse verwendet. Laut Django-Dokumentation:Dies ist die Magie, die das möglich macht. Sobald das Modell erstellt wurde,
self.field.rel.to.DoesNotExist
ist dies die nicht existierende Ausnahme für dieses Modell.quelle
Wenn Sie die zugehörige Modellklasse nicht importieren möchten, können Sie:
oder
Wo
related_field
ist der Feldname?quelle
Um diese Ausnahme im Allgemeinen abzufangen, können Sie dies tun
quelle
<Model>.DoesNotExist
tatDie
RelatedObjectDoesNotExist
Ausnahme wird zur Laufzeit dynamisch erstellt. Hier ist das relevante Code-Snippet für dieForwardManyToOneDescriptor
undReverseOneToOneDescriptor
Deskriptoren:Die Ausnahme erbt also von
<model name>.DoesNotExist
undAttributeError
. Tatsächlich lautet die vollständige MRO für diesen Ausnahmetyp:Der Grundservice ist man fangen kann
<model name>.DoesNotExist
,ObjectDoesNotExist
(Import ausdjango.core.exceptions
) oderAttributeError
, was auch immer die am meisten Sinn in Ihrem Kontext macht.quelle
Die Antwort von tdelaney eignet sich hervorragend für reguläre Codepfade. Wenn Sie jedoch wissen müssen, wie Sie diese Ausnahme in Tests abfangen können:
quelle
Etwas spät, aber hilfreich für andere.
2 Möglichkeiten, damit umzugehen.
1 :
Wenn wir eine Ausnahme machen müssen
2. Wenn Sie keine Ausnahme behandeln möchten
quelle