বস্তুটি বিদ্যমান থাকলে আমি কীভাবে তা পাই, না যদি তা না থাকে তবে তা কীভাবে পাওয়া যায়?


222

আমি যখন মডেল ম্যানেজারকে কোনও অবজেক্ট পেতে বলি, DoesNotExistযখন কোনও ম্যাচিং অবজেক্ট না থাকে তখন এটি উত্থাপিত হয়।

go = Content.objects.get(name="baby")

পরিবর্তে DoesNotExist, আমি পরিবর্তে কিভাবে হতে goপারে None?

উত্তর:


332

এটি করার মতো কোনও 'বিল্ট ইন' উপায় নেই। জ্যাঙ্গো প্রতিবারই ডোন নটএক্সিস্ট ব্যতিক্রম বাড়িয়ে তুলবে। অজগরটিকে এটিকে হ্যান্ডেল করার অদ্ভুত উপায়টি হ'ল এটি চেষ্টা করে ধরুন:

try:
    go = SomeModel.objects.get(foo='bar')
except SomeModel.DoesNotExist:
    go = None

আমি যা করেছি তা হ'ল সাবক্লাস মডেলগুলি an safe_getম্যানেজার, উপরের কোডের মতো একটি তৈরি করুন এবং আমার মডেলগুলির জন্য সেই ব্যবস্থাপকটি ব্যবহার করুন। এই ভাবে আপনি লিখতে পারেন: SomeModel.objects.safe_get(foo='bar')


7
ব্যতিক্রমটি আমদানি না করে সামার মডেল.ডোজন নটএক্সিস্টের দুর্দান্ত ব্যবহার।
সুপারিমেচ

195
এই দ্রবণটি চার লাইন দীর্ঘ। আমার জন্য এটি অনেক বেশি। জ্যাঙ্গো ১.6 এর সাহায্যে আপনি SomeModel.objects.filter(foo='bar').first()এই প্রথম ম্যাচটি বা কোনওটিই প্রদান করে না। এটি ব্যর্থ হয় না যদি এর মতো বেশ কয়েকটি দৃষ্টান্ত রয়েছেqueryset.get()
গেটল

9
আমি মনে করি ডিফল্ট কেসগুলি পরিচালনা করার ক্ষেত্রে ব্যতিক্রমগুলি অতিরিক্ত ব্যবহার করা খারাপ স্টাইল। হ্যাঁ, "অনুমতি চেয়ে ক্ষমা চাওয়া সহজ"। তবে একটি ব্যতিক্রম এখনও আমার চোখে ব্যতিক্রম হিসাবে ব্যবহার করা উচিত।
কনস্ট্যান্টিন শোবার্ট

8
সুস্পষ্ট বর্ণিত চেয়ে ভাল। ব্যবহারের জন্য পারফরম্যান্সের কারণ না থাকলে filter().first()আমার মনে হয় ব্যতিক্রমটি যাওয়ার উপায়।
খ্রিস্টিয়ানবন্দি

6
প্রথম () ব্যবহার করা কেবলমাত্র একটি ভাল ধারণা যদি আপনি যখন বহুগুণ হয় তখন যত্ন না করে। অন্যথায়, এই সমাধানটি সর্বোত্তম, কারণ আপনি যদি অপ্রত্যাশিতভাবে একাধিক অবজেক্টগুলি সন্ধান করেন তবে এটি এখনও একটি ব্যতিক্রম ছুঁড়ে ফেলবে যা আপনি সাধারণত সেই ক্ষেত্রে ঘটতে চান।
রসদবিধি

181

জাজানো ১.6 থেকে আপনি প্রথম () পদ্ধতিটি এর মতো ব্যবহার করতে পারেন :

Content.objects.filter(name="baby").first()

26
এক্ষেত্রে একাধিক ম্যাচ হলে কোনও ত্রুটি উত্থাপিত হয় না।
কনস্ট্যান্টিন শুবার্ট

7
'ফেরক্সটিএল' আপনার এই উত্তরটির জন্য @ গেটলিটিকে ক্রেডিট করতে হবে, কারণ তিনি আপনার পোস্টের এক বছর আগে গ্রহণযোগ্য উত্তরে এটি মন্তব্য করেছিলেন।
colm.anseo

7
@ কলিনেটর আমি বরং বলব গেটলিকে শিখতে হবে যে কোনও নতুন উত্তর মন্তব্য হিসাবে অন্তর্ভুক্ত নয় যদি তিনি তার স্ট্যাকওভারফ্লো খ্যাতিমান উত্থাপন করতে চান :) ফেরক্সটিএল একটি মন্তব্য হিসাবে লুকানো কিছু উত্তর হিসাবে আরও পরিষ্কার করার জন্য পয়েন্ট পেতে হবে। আপনার মন্তব্যটি আমার মনে হয় গেটলির পক্ষে যথেষ্ট ক্রেডিট এবং যদি এটি আপনার পরামর্শ হয় তবে উত্তরে যুক্ত করা উচিত নয়।
জোয়াকিম

3
@ জোয়াকিম একটি নতুন "উত্তর" পোস্ট করতে আমার কোনও সমস্যা নেই - কেবল যেখানে credit
ণ দেওয়ার দরকার

3
গৃহীত উত্তরের সাথে তুলনা করে এই পদ্ধতির কর্মক্ষমতা সম্পর্কে কী?
ম্যাক্সোর

36

জ্যাঙ্গো ডক্স থেকে

get()DoesNotExistপ্রদত্ত প্যারামিটারগুলির জন্য কোনও অবজেক্ট না পাওয়া গেলে একটি ব্যতিক্রম উত্থাপন করে । এই ব্যতিক্রমটি মডেল শ্রেণির একটি বৈশিষ্ট্যও। DoesNotExist থেকে ব্যতিক্রম উত্তরাধিকারীdjango.core.exceptions.ObjectDoesNotExist

আপনি ব্যতিক্রমটি ধরতে পারেন এবং Noneযেতে যেতে নির্ধারণ করতে পারেন।

from django.core.exceptions import ObjectDoesNotExist
try:
    go  = Content.objects.get(name="baby")
except ObjectDoesNotExist:
    go = None

33

আপনি এটির জন্য একটি জেনেরিক ফাংশন তৈরি করতে পারেন।

def get_or_none(classmodel, **kwargs):
    try:
        return classmodel.objects.get(**kwargs)
    except classmodel.DoesNotExist:
        return None

নীচের মত এটি ব্যবহার করুন:

go = get_or_none(Content,name="baby")

অন্য কোনও প্রবেশের সাথে মেলে নিলে আর কিছুই হবে না কন্টেন্ট এন্ট্রি ফিরিয়ে দেবে।

দ্রষ্টব্য: এটি ব্যতিক্রম উত্থাপন করবে মাল্টিপলঅবজেক্টস নাম = "শিশু" এর জন্য একাধিক এন্ট্রি ফিরে এলে পুনরায় চালু করা হবে



14

জিনিসগুলিকে সহজ করার জন্য, এখানে লেখা দুর্দান্ত কোডগুলির একটি স্নিপেট এখানে দেওয়া হয়েছে:

class MyManager(models.Manager):

    def get_or_none(self, **kwargs):
        try:
            return self.get(**kwargs)
        except ObjectDoesNotExist:
            return None

এবং তারপরে আপনার মডেলটিতে:

class MyModel(models.Model):
    objects = MyManager()

এটাই. এখন আপনার কাছে MyModel.objects.get () পাশাপাশি মাইমোডেল.ওবজেটস.সেট_অর_নোন () রয়েছে


7
এছাড়াও, আমদানি করতে ভুলবেন না: django.core. ব্যতিক্রমগুলি থেকে আমদানি করুন অবজেক্টডোস নট এক্সজিস্ট
মতি

13

আপনি existsএকটি ফিল্টার সঙ্গে ব্যবহার করতে পারে :

Content.objects.filter(name="baby").exists()
#returns False or True depending on if there is anything in the QS

আপনি কেবল এটির বিদ্যমান কিনা তা জানতে চাইলে কেবল তার বিকল্প


4
এটি উপস্থিত থাকলে অতিরিক্ত ডাটাবেস কল করতে পারে cause ভাল ধারণা নয়
ক্রিস্টোফার

ক্রিসটফার নিশ্চিত হন না যে কেন এটি অতিরিক্ত ডিবি কল হবে। অনুযায়ী ডক্স :Note: If you only want to determine if at least one result exists (and don’t need the actual objects), it’s more efficient to use exists().
অনুপম

2
@ ক্রিস্টোফার আমি মনে করি আপনি ঠিক বলেছেন। আমি এখন আবার প্রশ্নটি পড়েছি এবং ওপি আসলে আসল বস্তুটি ফিরে আসতে চায়। সুতরাং ডিবিতে ডাবল হিট হওয়ার কারণে অবজেক্টটি আনার আগে ক্লজ exists()সহ ব্যবহার করা হবে if। অন্য কারও সাহায্য করার ক্ষেত্রে আমি এখনও মন্তব্যটি রাখব।
অনুপম

7

আপনার মতামতের বিভিন্ন পয়েন্টে ব্যতিক্রমগুলি হ্যান্ডেল করা সত্যিই জটিল হতে পারে..এমন মডেলস.পি ফাইলটিতে একটি কাস্টম মডেল ম্যানেজারের সংজ্ঞা দেওয়ার বিষয়ে কি?

class ContentManager(model.Manager):
    def get_nicely(self, **kwargs):
        try:
            return self.get(kwargs)
        except(KeyError, Content.DoesNotExist):
            return None

এবং তারপরে বিষয়বস্তু মডেল শ্রেণিতে এটি অন্তর্ভুক্ত করুন

class Content(model.Model):
    ...
    objects = ContentManager()

এইভাবে এটি সহজেই ভিউগুলিতে ডিল করা যায় ie

post = Content.objects.get_nicely(pk = 1)
if post:
    # Do something
else:
    # This post doesn't exist

1
আমি এই সমাধানটি সত্যিই পছন্দ করি তবে পাইথন ৩.6 ব্যবহার করার সময় এটি এটিকে কাজে লাগাতে সক্ষম হয় নি। return self.get(**kwargs)আমার কাছে কাজ করার জন্য কনটেন্ট ম্যানেজারে ফিরতি পরিবর্তন করে একটি নোট রাখতে চেয়েছিলেন to উত্তরের সাথে কোনওরকম ভুল না বলা, পরবর্তী সংস্করণগুলির সাথে (বা অন্য যে কোনও কিছুই এটি আমার পক্ষে কাজ করা থেকে বিরত রেখেছে) ব্যবহার করে চেষ্টা করার জন্য কেবল একটি টিপ।
স্কাগজিলা

7

এটি এমন একটি বিরক্তিকর ফাংশন যা আপনি পুনরায় প্রয়োগ করতে চান না:

from annoying.functions import get_object_or_None
#...
user = get_object_or_None(Content, name="baby")

আমি কোডটি যাচাই করেছিলাম get_object_or_Noneকিন্তু দেখেছি যে এটি এখনও MultipleObjectsReturnedএকাধিক বস্তুর উত্থাপন করে । সুতরাং, ব্যবহারকারী একটি try-except(যার সাথে ফাংশনটি try-exceptইতিমধ্যে ইতিমধ্যে রয়েছে) এর আশেপাশে বিবেচনা করতে পারে ।
জন পাং

4

আপনি যদি একটি সাধারণ এক-লাইন সমাধান চান যা ব্যতিক্রম পরিচালনা, শর্তাধীন বিবৃতি বা জ্যাঙ্গো 1.6+ এর প্রয়োজনের সাথে জড়িত না থাকে তবে পরিবর্তে এটি করুন:

x = next(iter(SomeModel.objects.filter(foo='bar')), None)

4

আমি মনে করি এটি ব্যবহার করা খারাপ ধারণা নয় get_object_or_404()

from django.shortcuts import get_object_or_404

def my_view(request):
    my_object = get_object_or_404(MyModel, pk=1)

এই উদাহরণটি সমান:

from django.http import Http404

def my_view(request):
    try:
        my_object = MyModel.objects.get(pk=1)
    except MyModel.DoesNotExist:
        raise Http404("No MyModel matches the given query.")

আপনি জাজো অনলাইন ডকুমেন্টেশনে get_object_or_404 () সম্পর্কে আরও পড়তে পারেন ।


2

জ্যাঙ্গো ১.7 থেকে আপনার পছন্দ মতো করতে পারেন:

class MyQuerySet(models.QuerySet):

    def get_or_none(self, **kwargs):
        try:
            return self.get(**kwargs)
        except self.model.DoesNotExist:
            return None


class MyBaseModel(models.Model):

    objects = MyQuerySet.as_manager()


class MyModel(MyBaseModel):
    ...

class AnotherMyModel(MyBaseModel):
    ...

"মাইকিউয়ারিসেট.আস_ম্যানেজার ()" এর সুবিধাটি হ'ল নীচের উভয়টিই কাজ করবে:

MyModel.objects.filter(...).get_or_none()
MyModel.objects.get_or_none()

1

এখানে সহায়তা ফাংশনটির একটি প্রকরণ রয়েছে যা আপনাকে QuerySetউদাহরণস্বরূপ বিকল্প হিসাবে পাস করতে দেয় , যদি আপনি মডেলের allঅবজেক্টের ক্যোরিসেট (যেমন কোনও শিশু সম্পর্কিত আইটেমের সাবসেট থেকে অন্য কোনও ক্যুরিসেট থেকে অনন্য অবজেক্ট (উপস্থিত থাকলে) পেতে চান) মূল উদাহরণ):

def get_unique_or_none(model, queryset=None, **kwargs):
    """
        Performs the query on the specified `queryset`
        (defaulting to the `all` queryset of the `model`'s default manager)
        and returns the unique object matching the given
        keyword arguments.  Returns `None` if no match is found.
        Throws a `model.MultipleObjectsReturned` exception
        if more than one match is found.
    """
    if queryset is None:
        queryset = model.objects.all()
    try:
        return queryset.get(**kwargs)
    except model.DoesNotExist:
        return None

এটি দুটি উপায়ে ব্যবহার করা যেতে পারে, যেমন:

  1. obj = get_unique_or_none(Model, **kwargs) হিসাবে previosuly আলোচনা
  2. obj = get_unique_or_none(Model, parent.children, **kwargs)

1

ব্যতিক্রম ছাড়া:

if SomeModel.objects.filter(foo='bar').exists():
    x = SomeModel.objects.get(foo='bar')
else:
    x = None

একটি ব্যতিক্রম ব্যবহার:

try:
   x = SomeModel.objects.get(foo='bar')
except SomeModel.DoesNotExist:
   x = None

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


1

আমরা জাজানো বিল্টিন ব্যতিক্রমগুলি ব্যবহার করতে পারি যা নাম হিসাবে চিহ্নিত মডেলগুলির সাথে সংযুক্ত .DoesNotExist। সুতরাং, আমাদের ObjectDoesNotExistব্যতিক্রম আমদানি করতে হবে না ।

পরিবর্তে করছেন:

from django.core.exceptions import ObjectDoesNotExist

try:
    content = Content.objects.get(name="baby")
except ObjectDoesNotExist:
    content = None

আমরা এটা করতে পারি:

try:
    content = Content.objects.get(name="baby")
except Content.DoesNotExist:
    content = None

0

এটি জ্যাঙ্গোর get_object_or_404 এর কোনও অনুলিপি ব্যতীত পদ্ধতিটি ছাড়া আর কিছুই দেয় না। এটি only()কেবলমাত্র নির্দিষ্ট ক্ষেত্রগুলি পুনরুদ্ধারে যখন আমাদের ক্যোয়ারী ব্যবহার করতে হয় তখন এটি অত্যন্ত কার্যকর । এই পদ্ধতিটি কোনও মডেল বা ক্যোরিসেট গ্রহণ করতে পারে।

from django.shortcuts import _get_queryset


def get_object_or_none(klass, *args, **kwargs):
    """
    Use get() to return an object, or return None if object
    does not exist.
    klass may be a Model, Manager, or QuerySet object. All other passed
    arguments and keyword arguments are used in the get() query.
    Like with QuerySet.get(), MultipleObjectsReturned is raised if more than
    one object is found.
    """
    queryset = _get_queryset(klass)
    if not hasattr(queryset, 'get'):
        klass__name = klass.__name__ if isinstance(klass, type) else klass.__class__.__name__
        raise ValueError(
            "First argument to get_object_or_none() must be a Model, Manager, "
            "or QuerySet, not '%s'." % klass__name
        )
    try:
        return queryset.get(*args, **kwargs)
    except queryset.model.DoesNotExist:
        return None

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