আপনি কিভাবে এই ব্যতিক্রম ধরেন?


162

এই কোডটি জাঙ্গো / ডিবি / মডেল / ক্ষেত্রগুলিতে রয়েছে? এটি একটি ব্যতিক্রম তৈরি করে / সংজ্ঞা দেয়?

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

এটি জ্যাঙ্গো / ডিবি / মডেল / ক্ষেত্র / সম্পর্কিত.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

যা সম্ভবত তাই।


আপনি কীভাবে আমদানি করেছেন related?
জন জুইনক

4
AttributeErrorপরিবর্তে ব্যবহার করুনrelated.ReverseSingleRelatedObjectDescriptor.RelatedObjectDoesNotExist
ক্যাথরিন

হ্যাঁ @ জনজুইনক আমি সম্পর্কিত আমদানি করেছি।
নৌকা কোডার

উত্তর:


302

যদি আপনার সম্পর্কিত মডেলটিকে ফু বলা হয় তবে আপনি কেবল এটি করতে পারেন:

except Foo.DoesNotExist:

জাজানো বিস্ময়কর যখন এটি ভয়াবহ নয়। RelatedObjectDoesNotExistএমন একটি সম্পত্তি যা রান টাইম সময়ে গতিশীলভাবে নির্ধারিত হয় এমন এক প্রকারের ফেরত দেয়। এই ধরণেরটি self.field.rel.to.DoesNotExistবেস ক্লাস হিসাবে ব্যবহার করে । জাজানো ডকুমেন্টেশন অনুসারে:

অবজেক্টডোজনট এক্সজিস্ট এবং ডোন নটএক্সিস্ট

ব্যতিক্রম NoNotExist

DoesNotExist ব্যতিক্রম উত্থাপিত একটি বস্তু একটি ক্যোয়ারী দেওয়া পরামিতি জন্য পাওয়া যায় না যখন করা হয়। জ্যাঙ্গো খুঁজে পাওয়া যায়নি এমন বস্তুর শ্রেণি সনাক্ত করতে এবং / এর সাথে একটি নির্দিষ্ট মডেল শ্রেণি ধরতে আপনাকে অনুমতি দেওয়ার জন্য প্রতিটি মডেল শ্রেণীর একটি বৈশিষ্ট্য হিসাবে একটি নোনেটএক্সিস্ট ব্যতিক্রম সরবরাহ করে ।tryexcept

এটি সেই যাদু যা ঘটায়। একবার মডেলটি তৈরি হয়ে গেলে, সেই মডেলের self.field.rel.to.DoesNotExistজন্য কী অস্তিত্ব নেই exception


7
কারণ বাগটি জ্যাঙ্গোরেস্টফ্রেমওয়ার্কে ছিল এবং মডেলটি আসতে কিছুটা শক্ত। আমি অবজেক্টডনস এক্সজিস্ট ধরার জন্য স্থির হয়েছি।
নৌকোডার

3
আপনি অ্যাট্রিবিউটআরারও ব্যবহার করতে পারেন যা নির্দিষ্ট পরিস্থিতিতে একটি ভাল বিকল্প হতে পারে (আপনি যখন কোনও রেকর্ডের "অ্যাট্রিবিউট" অ্যাক্সেস করেন তখন এই ত্রুটিটি প্রায়শই ঘটে থাকে, সুতরাং এই বৈশিষ্ট্যটি কোনওটির সাথে সামঞ্জস্য করে কিনা আপনাকে এই ভাবে ট্র্যাক রাখতে হবে না) রেকর্ড করুন বা না
জর্দান রিইটার

1
হ্যাঁ ঠিক আছে। তবে কেন এটি কিছুই ফিরিয়ে দিতে পারে না? বিশেষ করে একের সাথে এক ক্ষেত্র। নাকি কোনও ভাল কারণ আছে?
নীল

61

আপনি যদি সম্পর্কিত মডেল শ্রেণিটি আমদানি করতে না চান তবে আপনি এটি করতে পারেন:

except MyModel.related_field.RelatedObjectDoesNotExist:

অথবা

except my_model_instance._meta.model.related_field.RelatedObjectDoesNotExist:

related_fieldমাঠের নাম কোথায়


7
আপনার বৃত্তাকার আমদানি এড়াতে হবে এমন ক্ষেত্রে এটি আসলে বেশ কার্যকর। ধন্যবাদ
জিওভান্নি দি মিলিয়া

40

সাধারণভাবে এই ব্যতিক্রমটি ধরতে, আপনি এটি করতে পারেন

from django.core.exceptions import ObjectDoesNotExist

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

2
আমি দেখতে পেয়েছি এটি আসলে প্রত্যাশার মতো ত্রুটিটি ধরেনি। <Model>.DoesNotExistকরেনি
এরিক Blum

1
@ এরিক ব্লুম <মডেল> .ডোজ নটএক্সিস্ট হ'ল অবজেক্টডোজন নটএক্সিস্টের বংশধর, যাতে এটি হওয়া উচিত নয়। এটি কেন ঘটছে তা খনন করতে পারেন বা আপনার কোড সম্পর্কে আরও বিশদ দিতে পারেন?
জাগস

10

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। আসলে, এই ব্যতিক্রম ধরণের সম্পূর্ণ এমআরও হ'ল:

[<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যা কিছু আপনার প্রসঙ্গে সর্বাধিক বোধ করে।


2

নিয়মিত কোড পাথের জন্য tdelaney এর উত্তর দুর্দান্ত, তবে পরীক্ষাগুলিতে কীভাবে এই ব্যতিক্রমটি ধরতে হয় তা আপনার যদি জানতে প্রয়োজন:

from django.core.exceptions import ObjectDoesNotExist

...

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

2

কিছুটা দেরি হলেও অন্যদের জন্য সহায়ক।

এটি পরিচালনা করার 2 উপায়।

1 ম:

আমাদের যখন ব্যতিক্রম ধরা দরকার

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

2 য়: কখন ব্যতিক্রম হ্যান্ডেল করতে চান না

>>> hasattr(p2, 'restaurant')
False
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.