programing

이 예외를 어떻게 잡습니까?

batch 2023. 6. 5. 23:43
반응형

이 예외를 어떻게 잡습니까?

이 코드는 django/db/db/sys/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/db/db/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

그래서 그럴 겁니다

관련 모델의 이름이 Foo인 경우 다음 작업을 수행할 수 있습니다.

except Foo.DoesNotExist:

장고는 무섭지 않을 때 정말 멋집니다. RelatedObjectDoesNotExist런타임에 동적으로 확인되는 형식을 반환하는 속성입니다.해당 유형은 다음을 사용합니다.self.field.rel.to.DoesNotExist기본급으로

장고 문서에 따르면:

존재하지 않음

예외. Model.존재하지 않음

이 예외는 ORM이 예상 개체를 찾을 수 없을 때 발생합니다.예를 들어, 에서는 지정된 조회에 대한 개체를 찾을 수 없을 때 이 개체를 올립니다.

장고는 각 모델 클래스의 속성으로 예외를 제공하여 찾을 수 없는 개체 클래스를 식별하므로 특정 모델 클래스에 대한 예외를 포착할 수 있습니다.

예외는 의 하위 클래스입니다.

이것이 그것을 가능하게 하는 마법입니다.일단 모델이 구축되면,self.field.rel.to.DoesNotExist해당 모델에 대한 실행 중지 예외입니다.

관련 모델 클래스를 가져오지 않으려면 다음을 수행할 수 있습니다.

except MyModel.related_field.RelatedObjectDoesNotExist:

또는

except my_model_instance._meta.model.related_field.RelatedObjectDoesNotExist:

어디에related_field필드 이름입니다.

다음과 같은 모델이 있다고 가정합니다.

class MainModel(Model):
    pass

class RelatedModel(Model):
    main = OneToOneField(MainModel, null=True, related_name="related")

다음을 얻을 수 있습니다.RelatedObjectDoesNotExist에 대한 예외.MainModel().related.

이 예외를 포착하기 위한 세 가지 옵션이 있으며, 이는 다음을 통해 확인할 수 있습니다..__class__.__mro__예외:

  1. MainModel.related.RelatedObjectDoesNotExist
  2. RelatedModel.DoesNotExist
  3. django.core.exceptions.ObjectDoesNotExist

주 모델. 관련.관련 개체가 없습니다.

RelatedObjectDoesNotExist질문이 찾고 있는 것이지만 null 가능한 것에 한정됩니다.OneToOneField:

try:
    # Your code here
except MainModel.related.RelatedObjectDoesNotExist:
    # Handle exception

관련 모델.존재하지 않음

Model.DoesNotExist의 부모 클래스입니다.RelatedObjectDoesNotExist이를 탐지하려면 문제의 모델을 가져올 수 있어야 하지만 이는 보다 일반적으로 유용한 코드 패턴입니다.

try:
    # Your code here
except OtherModel.DoesNotExist:
    # Handle exception

django.core.예외 사항개체가 없습니다.

ObjectDoesNotExist의 부모 클래스입니다.Model.DoesNotExist이렇게 하면 모든 모델에 대해 이 예외가 적용되므로 어떤 모델이 예외를 발생시킬지 모르는 경우에 유용합니다.

from django.core.exceptions import ObjectDoesNotExist

try:
    # Your code here
except ObjectDoesNotExist:
    # Handle exception

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

따라서 예외는 다음에서 상속됩니다.<model name>.DoesNotExist그리고.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'>]

기본적인 방법은 당신이 잡을 수 있다는 것입니다.<model name>.DoesNotExist,ObjectDoesNotExist((으)에서 django.core.exceptions) 또는AttributeError당신의 상황에서 가장 말이 되는 것은 무엇이든.

조금 늦었지만 다른 사람들에게 도움이 됩니다.

이것을 다루는 두 가지 방법.

첫 번째:

예외를 잡아야 할 때

>>> from django.core.exceptions import ObjectDoesNotExist
>>> try:
>>>     p2.restaurant
>>> except ObjectDoesNotExist:
>>>     print("There is no restaurant here.")
There is no restaurant here.

번째: 예외를 처리하고 싶지 않을 때

>>> hasattr(p2, 'restaurant')
False

tdelaney의 답변은 일반 코드 경로에 적합하지만 테스트에서 이 예외를 포착하는 방법을 알아야 할 경우:

from django.core.exceptions import ObjectDoesNotExist

...

    def testCompanyRequired(self):
        with self.assertRaises(ObjectDoesNotExist):
            employee = Employee.objects.create()

언급URL : https://stackoverflow.com/questions/26270042/how-do-you-catch-this-exception

반응형