Django 2.1 - QuerySet API reference

QuerySet API संदर्भ




django

QuerySet API संदर्भ

यह दस्तावेज़ QuerySet API के विवरण का वर्णन करता है। यह model और डेटाबेस क्वेरी गाइड में प्रस्तुत सामग्री पर बनाता है, इसलिए आप शायद इसे पढ़ने से पहले उन दस्तावेजों को पढ़ना और समझना चाहते हैं।

इस संदर्भ में हम डेटाबेस क्वेरी गाइड में प्रस्तुत उदाहरण वेबलॉग मॉडल का उपयोग करेंगे।

जब QuerySet का मूल्यांकन किया जाता है

आंतरिक रूप से, QuerySet का निर्माण, फ़िल्टर, कटा हुआ, और आमतौर पर डेटाबेस को मार डाले बिना किया जा सकता है। डेटाबेस गतिविधि वास्तव में तब तक नहीं होती है जब तक आप क्वेरीसेट का मूल्यांकन करने के लिए कुछ नहीं करते हैं।

आप निम्नलिखित तरीकों से एक QuerySet मूल्यांकन कर सकते हैं:

  • पुनरावृत्ति। एक QuerySet है, और यह पहली बार अपने डेटाबेस क्वेरी को निष्पादित करता है जब आप इस पर पुनरावृति करते हैं। उदाहरण के लिए, यह डेटाबेस में सभी प्रविष्टियों के शीर्षक को प्रिंट करेगा:

    for e in Entry.objects.all():
        print(e.headline)
    

    नोट: यदि आप कम से कम एक परिणाम मौजूद है, तो यह निर्धारित करने के लिए इसका उपयोग न करें। यह exists() का उपयोग करने के लिए अधिक कुशल है।

  • टुकड़ा करने की क्रिया। जैसा कि सीमित क्वेरीरीसेट्स में बताया गया है, अजगर की सरणी-स्लाइसिंग सिंटैक्स का उपयोग करके एक QuerySet को कटा हुआ किया जा सकता है। एक QuerySet आमतौर पर एक और QuerySet , लेकिन अगर आप स्लाइस सिंटैक्स के "स्टेप" पैरामीटर का उपयोग करते हैं, और एक सूची वापस करेगा, तो Django डेटाबेस क्वेरी को निष्पादित करेगा। एक QuerySet मूल्यांकन किया गया है जिसे QuerySet भी एक सूची देता है।

    इस बात पर भी ध्यान दें कि एक QuerySet QuerySet को QuerySet करने के QuerySet , एक और QuerySet लौटाता है, इसे और अधिक संशोधित करता है (जैसे, अधिक फिल्टर जोड़ना, या ऑर्डर को संशोधित करना) की अनुमति नहीं है, क्योंकि यह SQL में अच्छी तरह से अनुवाद नहीं करता है और इसका कोई स्पष्ट अर्थ भी नहीं होगा।

  • अचार बनाना / कैशिंग। QuerySets अचार करते समय क्या शामिल है, इसके विवरण के लिए निम्न अनुभाग देखें। इस खंड के प्रयोजनों के लिए महत्वपूर्ण बात यह है कि परिणाम डेटाबेस से पढ़े जाते हैं।
  • रेपर ()। जब आप उस पर repr() कहते हैं तो एक QuerySet का मूल्यांकन किया जाता है। यह पायथन इंटरएक्टिव इंटरप्रेटर में सुविधा के लिए है, इसलिए आप एपीआई को इंटरएक्टिव का उपयोग करते समय तुरंत अपने परिणाम देख सकते हैं।
  • लेन ()। जब आप इस पर len() कहते हैं, तो एक QuerySet का मूल्यांकन किया जाता है। जैसा कि आप उम्मीद कर सकते हैं, परिणाम सूची की लंबाई लौटाता है।

    नोट: यदि आपको सेट में रिकॉर्ड की संख्या निर्धारित करने की आवश्यकता है (और वास्तविक वस्तुओं की आवश्यकता नहीं है), तो SQL के SELECT COUNT(*) का उपयोग करके डेटाबेस स्तर पर एक गिनती को संभालने के लिए यह अधिक कुशल है। Django इस कारण के लिए एक count() विधि प्रदान करता है।

  • सूची()। उस पर list() कॉल करके एक QuerySet का बल मूल्यांकन। उदाहरण के लिए:

    entry_list = list(Entry.objects.all())
    
  • bool ()। एक बूलियन संदर्भ में QuerySet परीक्षण करना, जैसे कि bool() , or , या if एक बयान का उपयोग करना, तो क्वेरी को निष्पादित किया जाएगा। यदि कम से कम एक परिणाम है, तो QuerySet True , अन्यथा False । उदाहरण के लिए:

    if Entry.objects.filter(headline="Test"):
       print("There is at least one Entry with the headline Test")
    

    नोट: यदि आप केवल यह निर्धारित करना चाहते हैं कि कम से कम एक परिणाम मौजूद है (और वास्तविक वस्तुओं की आवश्यकता नहीं है), इसका उपयोग करना अधिक कुशल है exists()

अचार QuerySet एस

यदि आप एक QuerySet pickle QuerySet , तो यह सभी परिणामों को अचार बनाने से पहले मेमोरी में लोड करने के लिए बाध्य करेगा। आमतौर पर अचार को कैशिंग के अग्रदूत के रूप में उपयोग किया जाता है और जब कैश्ड क्वेरी को पुनः लोड किया जाता है, तो आप चाहते हैं कि परिणाम पहले से मौजूद हों और उपयोग के लिए तैयार हों (डेटाबेस से पढ़ने में कुछ समय लग सकता है, कैशिंग के उद्देश्य को हराते हुए)। इसका मतलब यह है कि जब आप किसी QuerySet , तो उस समय इसके परिणाम शामिल होते हैं, जो डेटाबेस में वर्तमान में मौजूद परिणामों के बजाय, इसे चुना गया था।

यदि आप केवल बाद में डेटाबेस से QuerySet को फिर से बनाने के लिए आवश्यक जानकारी को अचार करना चाहते हैं, तो QuerySet की query विशेषता को QuerySet । फिर आप इस तरह से कुछ कोड का उपयोग करके मूल QuerySet (बिना किसी परिणाम के लोड किए गए) को फिर से बना सकते हैं:

>>> import pickle
>>> query = pickle.loads(s)     # Assuming 's' is the pickled string.
>>> qs = MyModel.objects.all()
>>> qs.query = query            # Restore the original 'query'.

query विशेषता एक अपारदर्शी वस्तु है। यह क्वेरी निर्माण के आंतरिक का प्रतिनिधित्व करता है और सार्वजनिक एपीआई का हिस्सा नहीं है। हालांकि, यह सुरक्षित है (और पूरी तरह से समर्थित) अचार को अछूता है और यहां बताए अनुसार विशेषता की सामग्री को हटा दें।

आप अचार को संस्करणों के बीच साझा नहीं कर सकते

QuerySets अचार केवल Django के संस्करण के लिए मान्य हैं जो उन्हें उत्पन्न करने के लिए उपयोग किया गया था। यदि आप Django वर्जन N का उपयोग करके अचार बनाते हैं, तो इस बात की कोई गारंटी नहीं है कि अचार Django के संस्करण N + 1 के साथ पढ़ने योग्य होगा। अचार को दीर्घकालिक अभिलेखीय रणनीति के भाग के रूप में उपयोग नहीं किया जाना चाहिए।

चूंकि अचार संगतता त्रुटियों का निदान करना मुश्किल हो सकता है, जैसे कि चुपचाप भ्रष्ट वस्तुओं, एक RuntimeWarning तब उठाया जाता है जब आप एक जिंजो संस्करण में एक क्वेरीसेट को अनप्लिक करने की कोशिश करते हैं जो उस से अलग है जिसमें इसे चुना गया था।

QuerySet API

यहाँ एक QuerySet की औपचारिक घोषणा है:

class QuerySet(model=None, query=None, using=None) [source]

आमतौर पर जब आप एक QuerySet साथ इंटरैक्ट करेंगे तो आप इसका उपयोग फिल्टर का उपयोग करके करेंगे। इस कार्य को करने के लिए, अधिकांश QuerySet पद्धतियाँ नए QuerySet । इन तरीकों को बाद में इस खंड में विस्तार से कवर किया गया है।

QuerySet वर्ग की दो सार्वजनिक विशेषताएँ हैं जिनका उपयोग आप आत्मनिरीक्षण के लिए कर सकते हैं:

ordered

यदि QuerySet का आदेश दिया गया है तो यह True है - अर्थात मॉडल पर एक QuerySet order_by() खंड या एक डिफ़ॉल्ट आदेश है। False अन्यथा।

db

यदि इस क्वेरी को अभी निष्पादित किया जाता है तो डेटाबेस का उपयोग किया जाएगा।

ध्यान दें

QuerySet लिए query पैरामीटर मौजूद है ताकि विशेष क्वेरी उप-वर्ग आंतरिक क्वेरी स्थिति का पुनर्निर्माण कर सकें। पैरामीटर का मान उस क्वेरी स्थिति का एक अपारदर्शी प्रतिनिधित्व है और एक सार्वजनिक एपीआई का हिस्सा नहीं है। इसे सीधे शब्दों में कहें: यदि आपको पूछने की आवश्यकता है, तो आपको इसका उपयोग करने की आवश्यकता नहीं है।

ऐसे तरीके जो नए QuerySet

Django, QuerySet परिशोधन विधियों की एक श्रृंखला प्रदान करता है जो QuerySet द्वारा लौटाए गए परिणामों के प्रकारों को संशोधित QuerySet या जिस तरह से इसकी SQL क्वेरी निष्पादित होती है।

filter()

filter(**kwargs)

दिए गए लुकअप मापदंडों से मेल खाने वाली वस्तुओं से युक्त एक नया QuerySet लौटाता है।

लुकअप पैरामीटर ( **kwargs ) नीचे दिए गए फ़ील्ड लुकअप में वर्णित प्रारूप में होना चाहिए। एकाधिक मापदंडों के माध्यम से AND अंतर्निहित SQL स्टेटमेंट में शामिल हो गए हैं।

यदि आपको अधिक जटिल प्रश्नों को निष्पादित करने की आवश्यकता है (उदाहरण के लिए, OR कथन वाले प्रश्न), तो आप Q objects उपयोग कर सकते हैं।

exclude()

exclude(**kwargs)

दिए गए लुकअप मापदंडों से मेल खाने वाली वस्तुओं से युक्त एक नया QuerySet लौटाता है।

लुकअप पैरामीटर ( **kwargs ) नीचे दिए गए फ़ील्ड लुकअप में वर्णित प्रारूप में होना चाहिए। एकाधिक पैरामीटर के माध्यम से AND अंतर्निहित SQL स्टेटमेंट में शामिल हो जाते हैं, और पूरी चीज़ एक NOT() में संलग्न है।

यह उदाहरण उन सभी प्रविष्टियों को शामिल करता है जिनका pub_date बाद में 2005-1-3 की तुलना में है और जिसका headline "हैलो" है:

Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello')

SQL शब्दों में, जो इसका मूल्यांकन करता है:

SELECT ...
WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello')

यह उदाहरण उन सभी प्रविष्टियों को शामिल करता है जिनका pub_date बाद में 2005-1-3 की तुलना में है या जिनकी शीर्षक "Hello" है:

Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3)).exclude(headline='Hello')

SQL शब्दों में, जो इसका मूल्यांकन करता है:

SELECT ...
WHERE NOT pub_date > '2005-1-3'
AND NOT headline = 'Hello'

नोट दूसरा उदाहरण अधिक प्रतिबंधात्मक है।

यदि आपको अधिक जटिल प्रश्नों को निष्पादित करने की आवश्यकता है (उदाहरण के लिए, OR कथन वाले प्रश्न), तो आप Q objects उपयोग कर सकते हैं।

annotate()

annotate(*args, **kwargs)

क्वेरी ऑब्जेक्ट की प्रदान की गई सूची के साथ QuerySet में प्रत्येक ऑब्जेक्ट को एनोटेट करता है। एक अभिव्यक्ति एक साधारण मूल्य हो सकता है, मॉडल (या किसी भी संबंधित मॉडल) पर एक क्षेत्र का संदर्भ, या एक समग्र अभिव्यक्ति (औसत, रकम, आदि) उन वस्तुओं पर गणना की गई है जो वस्तुओं में संबंधित हैं QuerySet

annotate() करने के लिए प्रत्येक तर्क annotate() एक एनोटेशन है जिसे QuerySet में प्रत्येक ऑब्जेक्ट में जोड़ा जाएगा जो वापस आ गया है।

Django द्वारा प्रदान किए जाने वाले एकत्रीकरण कार्य नीचे दिए गए एकत्रीकरण कार्यों में वर्णित हैं।

कीवर्ड तर्कों का उपयोग करते हुए निर्दिष्ट एनोटेशन के लिए उपनाम के रूप में कीवर्ड का उपयोग करेगा। अनाम तर्कों में उनके लिए एक उपनाम उत्पन्न होगा जो कुल कार्य और मॉडल क्षेत्र के नाम के आधार पर एकत्र किया जाएगा। केवल एकल फ़ील्ड को संदर्भित करने वाले समग्र भाव अनाम तर्क हो सकते हैं। बाकी सब कुछ एक कीवर्ड तर्क होना चाहिए।

उदाहरण के लिए, यदि आप ब्लॉग की सूची में हेरफेर कर रहे हैं, तो आप यह निर्धारित करना चाहते हैं कि प्रत्येक ब्लॉग में कितनी प्रविष्टियाँ की गई हैं:

>>> from django.db.models import Count
>>> q = Blog.objects.annotate(Count('entry'))
# The name of the first blog
>>> q[0].name
'Blogasaurus'
# The number of entries on the first blog
>>> q[0].entry__count
42

Blog मॉडल अपने आप में एक entry__count विशेषता को परिभाषित नहीं करता है, लेकिन कुल फ़ंक्शन को निर्दिष्ट करने के लिए एक कीवर्ड तर्क का उपयोग करके, आप एनोटेशन के नाम को नियंत्रित कर सकते हैं:

>>> q = Blog.objects.annotate(number_of_entries=Count('entry'))
# The number of entries on the first blog, using the name provided
>>> q[0].number_of_entries
42

एकत्रीकरण की गहन चर्चा के लिए, एकत्रीकरण पर विषय मार्गदर्शिका देखें।

order_by()

order_by(*fields)

डिफ़ॉल्ट रूप से, QuerySet द्वारा लौटाए गए परिणाम मॉडल के Meta में ordering विकल्प द्वारा दिए गए ऑर्डरिंग टपल द्वारा आदेशित किए जाते हैं। आप QuerySet विधि का उपयोग करके इसे प्रति- QuerySet आधार पर ओवरराइड कर सकते हैं।

उदाहरण:

Entry.objects.filter(pub_date__year=2005).order_by('-pub_date', 'headline')

उपरोक्त परिणाम pub_date अवरोही, फिर आरोही headline द्वारा आदेशित किया जाएगा। "-pub_date" सामने नकारात्मक संकेत अवरोही क्रम को दर्शाता है। आरोही क्रम निहित है। बेतरतीब ढंग से ऑर्डर करने के लिए, "?" , इस तरह:

Entry.objects.order_by('?')

नोट: order_by('?') क्वेरीज़ आपके द्वारा उपयोग किए जा रहे डेटाबेस बैकेंड के आधार पर महंगी और धीमी हो सकती हैं।

किसी भिन्न मॉडल में फ़ील्ड द्वारा ऑर्डर करने के लिए, उसी सिंटैक्स का उपयोग करें जब आप मॉडल संबंधों में क्वेरी कर रहे हों। यही है, फ़ील्ड का नाम, उसके बाद एक डबल अंडरस्कोर ( __ ), उसके बाद नए मॉडल में फ़ील्ड का नाम, और इतने पर जैसे कि आप शामिल होना चाहते हैं। उदाहरण के लिए:

Entry.objects.order_by('blog__name', 'headline')

यदि आप किसी अन्य मॉडल से संबंधित फ़ील्ड द्वारा ऑर्डर करने का प्रयास करते हैं, तो Django संबंधित मॉडल पर डिफ़ॉल्ट ऑर्डरिंग का उपयोग करेगा, या संबंधित मॉडल की प्राथमिक कुंजी द्वारा ऑर्डर नहीं Meta.ordering यदि कोई Meta.ordering निर्दिष्ट नहीं है। उदाहरण के लिए, चूंकि Blog मॉडल में कोई डिफ़ॉल्ट क्रम निर्दिष्ट नहीं है:

Entry.objects.order_by('blog')

... इसके समान है:

Entry.objects.order_by('blog__id')

यदि Blog का ordering = ['name'] , तो पहली क्वेरी निम्न के समान होगी:

Entry.objects.order_by('blog__name')

आप अभिव्यक्ति पर asc() या desc() कॉल करके क्वेरी के भावों के अनुसार भी ऑर्डर कर सकते हैं:

Entry.objects.order_by(Coalesce('summary', 'headline').desc())

संबंधित मॉडल में फ़ील्ड द्वारा ऑर्डर करते समय सतर्क रहें यदि आप भी distinct() का उपयोग कर रहे हैं। संबंधित मॉडल कैसे अपेक्षित परिणाम बदल सकते हैं, इसकी व्याख्या के लिए नोट को distinct() देखें।

ध्यान दें

परिणामों को ऑर्डर करने के लिए एक बहु-मूल्यवान फ़ील्ड निर्दिष्ट करने की अनुमति है (उदाहरण के लिए, एक ManyToManyField फ़ील्ड, या एक ManyToManyField फ़ील्ड का रिवर्स रिलेशन)।

इस मामले पर विचार करें:

class Event(Model):
   parent = models.ForeignKey(
       'self',
       on_delete=models.CASCADE,
       related_name='children',
   )
   date = models.DateField()

Event.objects.order_by('children__date')

यहां, संभावित रूप से प्रत्येक Event लिए कई ऑर्डर करने वाले डेटा हो सकते हैं; कई children साथ प्रत्येक Event को नए QuerySet में कई बार लौटा दिया जाएगा जो QuerySet order_by() बनाता है। दूसरे शब्दों में, QuerySet पर QuerySet order_by() का उपयोग करके आप जिस आइटम पर काम करना शुरू कर रहे थे, उससे अधिक आइटम वापस कर सकते हैं - जो कि न तो अपेक्षित है और न ही उपयोगी है।

इस प्रकार, परिणाम का आदेश देने के लिए बहु-मूल्यवान फ़ील्ड का उपयोग करते समय ध्यान रखें। यदि आप यह सुनिश्चित कर सकते हैं कि आपके द्वारा ऑर्डर किए जा रहे प्रत्येक आइटम के लिए केवल एक डेटा ऑर्डर टुकड़ा होगा, तो यह दृष्टिकोण समस्याओं को प्रस्तुत नहीं करना चाहिए। यदि नहीं, तो सुनिश्चित करें कि परिणाम वही हैं जो आप उम्मीद करते हैं।

यह निर्दिष्ट करने का कोई तरीका नहीं है कि आदेश संवेदनशील होना चाहिए या नहीं। केस-सेंसिटिविटी के संबंध में, Django परिणाम का आदेश देगा हालांकि आपका डेटाबेस बैकएंड सामान्य रूप से उन्हें आदेश देता है।

आप लोअर के साथ लोअरकेस में परिवर्तित फ़ील्ड द्वारा ऑर्डर कर सकते हैं जो केस-सुसंगत ऑर्डर प्राप्त करेगा:

Entry.objects.order_by(Lower('headline').desc())

यदि आप नहीं चाहते हैं कि कोई भी ऑर्डर क्वेरी पर लागू किया जाए, तो डिफ़ॉल्ट ऑर्डर भी नहीं, order_by() बिना किसी पैरामीटर के।

आप यह बता सकते हैं कि QuerySet.ordered विशेषता की जाँच करके कोई क्वेरी का आदेश दिया गया है या नहीं, जो कि True होगा यदि QuerySet को किसी भी तरह से आदेश दिया गया है।

प्रत्येक order_by() कॉल किसी भी पिछले ऑर्डर को साफ कर देगी। उदाहरण के लिए, इस क्वेरी का आदेश pub_date द्वारा दिया जाएगा और headline नहीं:

Entry.objects.order_by('headline').order_by('pub_date')

चेतावनी

ऑर्डर देना एक मुफ्त ऑपरेशन नहीं है। प्रत्येक क्षेत्र जिसे आप ऑर्डर करने के लिए जोड़ते हैं, आपके डेटाबेस में खर्च होता है। आपके द्वारा जोड़े गए प्रत्येक विदेशी कुंजी में निहित सभी डिफ़ॉल्ट आदेश भी शामिल होंगे।

यदि किसी क्वेरी में कोई आदेश निर्दिष्ट नहीं है, तो परिणाम अनिर्दिष्ट क्रम में डेटाबेस से वापस कर दिए जाते हैं। किसी विशेष ऑर्डर की गारंटी केवल तभी दी जाती है जब फ़ील्ड के एक सेट द्वारा ऑर्डर किया जाता है जो परिणामों में प्रत्येक वस्तु की विशिष्ट पहचान करता है। उदाहरण के लिए, यदि कोई name फ़ील्ड अद्वितीय नहीं है, तो उसके द्वारा आदेश देना समान नाम वाले ऑब्जेक्ट को हमेशा उसी क्रम में दिखाई देने की गारंटी नहीं देगा।

reverse()

reverse()

उस क्रम को उलटने के लिए reverse() पद्धति का उपयोग करें जिसमें किसी क्वेरीसेट के तत्व वापस किए जाते हैं। कॉलिंग reverse() दूसरी बार वापस आकर सामान्य दिशा में वापस आ जाती है।

क्वेरी में "अंतिम" पांच आइटम प्राप्त करने के लिए, आप ऐसा कर सकते हैं:

my_queryset.reverse()[:5]

ध्यान दें कि यह पायथन में एक अनुक्रम के अंत से टुकड़ा करने की क्रिया के समान नहीं है। उपरोक्त उदाहरण पहले अंतिम आइटम को लौटाएगा, फिर पेनॉल्ट आइटम इत्यादि। यदि हमारे पास पायथन अनुक्रम था और seq[-5:] , तो हम पहले पांचवें-अंतिम आइटम को देखेंगे। Django पहुँच के उस मोड का समर्थन नहीं करता है (अंत से टुकड़ा करना), क्योंकि यह SQL में कुशलतापूर्वक करना संभव नहीं है।

इसके अलावा, ध्यान दें कि reverse() को आम तौर पर केवल एक QuerySet पर बुलाया जाना चाहिए जिसमें एक परिभाषित आदेश है (उदाहरण के लिए, जब एक मॉडल के खिलाफ क्वेरी जो एक डिफ़ॉल्ट ऑर्डर को परिभाषित करता है, या जब order_by() का उपयोग करते हुए)। यदि किसी दिए गए QuerySet लिए इस तरह के आदेश को परिभाषित नहीं किया गया है, तो उस पर reverse() कॉलिंग reverse() का कोई वास्तविक प्रभाव नहीं है ( reverse() कॉल करने से पहले ऑर्डर अपरिभाषित था reverse() , और बाद में अपरिभाषित रहेगा।

distinct()

distinct(*fields)

एक नया QuerySet जो अपनी SQL क्वेरी में SELECT DISTINCT का उपयोग करता है। यह क्वेरी परिणामों से डुप्लिकेट पंक्तियों को समाप्त करता है।

डिफ़ॉल्ट रूप से, QuerySet डुप्लिकेट पंक्तियों को समाप्त नहीं करेगी। व्यवहार में, यह शायद ही कभी एक समस्या है, क्योंकि Blog.objects.all() जैसे सरल प्रश्न डुप्लिकेट परिणाम पंक्तियों की संभावना का परिचय नहीं देते हैं। हालाँकि, यदि आपकी क्वेरी कई तालिकाएँ फैलाती है, तो QuerySet का मूल्यांकन करने पर डुप्लिकेट परिणाम प्राप्त करना संभव है। जब आप distinct() उपयोग करेंगे।

ध्यान दें

एक order_by() कॉल में उपयोग किए जाने वाले किसी भी फ़ील्ड को SQL SELECT कॉलम में शामिल किया गया है। यह कभी-कभी अनपेक्षित परिणाम पैदा कर सकता है जब distinct() के साथ संयोजन में उपयोग किया जाता है। यदि आप संबंधित मॉडल से फ़ील्ड्स ऑर्डर करते हैं, तो उन फ़ील्ड्स को चयनित कॉलमों में जोड़ा जाएगा और वे अन्यथा डुप्लिकेट पंक्तियाँ अलग-अलग दिखाई दे सकती हैं। चूंकि अतिरिक्त कॉलम लौटे परिणामों में नहीं दिखाई देते हैं (वे केवल ऑर्डर करने के लिए समर्थन करने के लिए हैं), यह कभी-कभी ऐसा लगता है कि गैर-विशिष्ट परिणाम वापस किए जा रहे हैं।

इसी प्रकार, यदि आप चयनित कॉलमों को प्रतिबंधित करने के लिए किसी values() क्वेरी का उपयोग करते हैं, तो किसी भी order_by() (या डिफ़ॉल्ट मॉडल ऑर्डरिंग) में उपयोग किए गए कॉलम अभी भी शामिल होंगे और परिणामों की विशिष्टता को प्रभावित कर सकते हैं।

यहां नैतिक यह है कि यदि आप distinct() संबंधित मॉडलों द्वारा ऑर्डर करने के बारे में सावधानी बरत रहे हैं। इसी तरह, distinct() और values() एक साथ उपयोग करते समय, फ़ील्ड द्वारा ऑर्डर करते समय सावधान रहें न कि values() कॉल में।

केवल उन पोस्टग्रेएसक्यूएल पर, जिन क्षेत्रों में DISTINCT को आवेदन करना चाहिए, उनके नाम निर्दिष्ट करने के लिए आप स्थिति संबंधी तर्क ( *fields ) पास कर सकते हैं। यह SQL क्वेरी SELECT DISTINCT ON एक SELECT DISTINCT ON अनुवाद करता है। यहाँ अंतर है। एक सामान्य distinct() कॉल के लिए, डेटाबेस प्रत्येक पंक्ति में प्रत्येक क्षेत्र की तुलना करते समय निर्धारित करता है कि कौन सी पंक्तियाँ अलग हैं। निर्दिष्ट फ़ील्ड नामों के साथ एक distinct() कॉल के लिए, डेटाबेस केवल निर्दिष्ट फ़ील्ड नामों की तुलना करेगा।

ध्यान दें

जब आप फ़ील्ड नाम निर्दिष्ट करते हैं, तो आपको QuerySet में एक QuerySet order_by() प्रदान करना होगा , और QuerySet order_by() में फ़ील्ड को उसी क्रम में फ़ील्ड को distinct() शुरू करना होगा।

उदाहरण के लिए, SELECT DISTINCT ON (a) आपको कॉलम a में प्रत्येक मान के लिए पहली पंक्ति देता a । यदि आप कोई आदेश निर्दिष्ट नहीं करते हैं, तो आपको कुछ मनमानी पंक्ति मिल जाएगी।

उदाहरण (पहले के बाद जो केवल PostgreSQL पर काम करेंगे):

>>> Author.objects.distinct()
[...]

>>> Entry.objects.order_by('pub_date').distinct('pub_date')
[...]

>>> Entry.objects.order_by('blog').distinct('blog')
[...]

>>> Entry.objects.order_by('author', 'pub_date').distinct('author', 'pub_date')
[...]

>>> Entry.objects.order_by('blog__name', 'mod_date').distinct('blog__name', 'mod_date')
[...]

>>> Entry.objects.order_by('author', 'pub_date').distinct('author')
[...]

ध्यान दें

ध्यान रखें कि order_by() परिभाषित किए गए किसी भी डिफ़ॉल्ट संबंधित मॉडल ऑर्डर का उपयोग करता है। आपको संबंध _id या संदर्भित फ़ील्ड द्वारा स्पष्ट रूप से आदेश देना पड़ सकता है ताकि यह सुनिश्चित किया जा सके कि ORDER BY खंड के आरंभ में DISTINCT ON अभिव्यक्तियाँ मेल खाती हैं। उदाहरण के लिए, यदि Blog मॉडल ने name एक Meta.ordering परिभाषित किया है:

Entry.objects.order_by('blog').distinct('blog')

... काम नहीं करेगा क्योंकि क्वेरी को blog__name द्वारा आदेश दिया जाएगा इस प्रकार अभिव्यक्ति DISTINCT ON बेमेल किया जाएगा। आपको स्पष्ट रूप से संबंध के लिए आदेश देना होगा blog_id फ़ील्ड (इस मामले में blog_id ) या संदर्भित एक ( blog__pk ) दोनों अभिव्यक्तियों का मिलान सुनिश्चित करने के लिए।

values()

values(*fields, **expressions)

एक QuerySet लौटाता है जो डिक्शनरी के रूप में उपयोग किए जाने पर मॉडल के उदाहरणों के बजाय शब्दकोशों को लौटाता है।

उन शब्दकोशों में से प्रत्येक एक ऑब्जेक्ट का प्रतिनिधित्व करता है, जिसमें मॉडल ऑब्जेक्ट्स के विशेषता नामों के अनुरूप कुंजियां होती हैं।

यह उदाहरण सामान्य मॉडल वस्तुओं के साथ values() के शब्दकोशों की तुलना करता है:

# This list contains a Blog object.
>>> Blog.objects.filter(name__startswith='Beatles')
<QuerySet [<Blog: Beatles Blog>]>

# This list contains a dictionary.
>>> Blog.objects.filter(name__startswith='Beatles').values()
<QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]>

values() पद्धति वैकल्पिक स्थिति संबंधी तर्क, *fields लेती है, जो फ़ील्ड नामों को निर्दिष्ट करती है, जिनके लिए SELECT सीमित होना चाहिए। यदि आप फ़ील्ड निर्दिष्ट करते हैं, तो प्रत्येक शब्दकोश में आपके द्वारा निर्दिष्ट फ़ील्ड के लिए फ़ील्ड कुंजी / मान होंगे। यदि आप फ़ील्ड निर्दिष्ट नहीं करते हैं, तो प्रत्येक शब्दकोश में डेटाबेस तालिका में प्रत्येक फ़ील्ड के लिए एक कुंजी और मान होगा।

उदाहरण:

>>> Blog.objects.values()
<QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]>
>>> Blog.objects.values('id', 'name')
<QuerySet [{'id': 1, 'name': 'Beatles Blog'}]>

values() विधि वैकल्पिक कीवर्ड तर्क, **expressions भी लेती है, जो annotate() से होकर गुजरती हैं।

>>> from django.db.models.functions import Lower
>>> Blog.objects.values(lower_name=Lower('name'))
<QuerySet [{'lower_name': 'beatles blog'}]>

आप ऑर्डर करने में बिल्ट-इन और कस्टम लुक्स का उपयोग कर सकते हैं। उदाहरण के लिए:

>>> from django.db.models import CharField
>>> from django.db.models.functions import Lower
>>> CharField.register_lookup(Lower)
>>> Blog.objects.values('name__lower')
<QuerySet [{'name__lower': 'beatles blog'}]>
Django 2.1 में परिवर्तित:

लुकअप के लिए समर्थन जोड़ा गया था।

एक values() खंड के भीतर एक ही values() खंड के भीतर अन्य तर्कों से पहले एक खंड लागू किया जाता है। यदि आपको किसी अन्य मान से समूह बनाने की आवश्यकता है, तो इसे पहले के values() खंड में जोड़ें। उदाहरण के लिए:

>>> from django.db.models import Count
>>> Blog.objects.values('entry__authors', entries=Count('entry'))
<QuerySet [{'entry__authors': 1, 'entries': 20}, {'entry__authors': 1, 'entries': 13}]>
>>> Blog.objects.values('entry__authors').annotate(entries=Count('entry'))
<QuerySet [{'entry__authors': 1, 'entries': 33}]>

कुछ सूक्ष्मताएँ जो ध्यान देने योग्य हैं:

  • यदि आपके पास एक फ़ील्ड है जिसे foo कहा जाता है जो कि एक ForeignKey , तो डिफ़ॉल्ट values() कॉल एक शब्दकोश कुंजी foo_id जिसे foo_id कहा जाता है, क्योंकि यह छिपे हुए मॉडल विशेषता का नाम है जो वास्तविक मूल्य को संग्रहीत करता है ( foo विशेषता संबंधित मॉडल को संदर्भित करता है )। जब आप values() को बुला रहे values() और फ़ील्ड नामों में पास हो रहे हैं, तो आप foo या foo_id में पास कर सकते हैं और आपको वही चीज़ वापस मिल जाएगी (शब्दकोश कुंजी आपके द्वारा पारित फ़ील्ड नाम से मेल खाएगी)।

    उदाहरण के लिए:

    >>> Entry.objects.values()
    <QuerySet [{'blog_id': 1, 'headline': 'First Entry', ...}, ...]>
    
    >>> Entry.objects.values('blog')
    <QuerySet [{'blog': 1}, ...]>
    
    >>> Entry.objects.values('blog_id')
    <QuerySet [{'blog_id': 1}, ...]>
    
  • values() का उपयोग values() distinct() साथ मिलकर distinct() , अवगत रहें कि आदेश परिणामों को प्रभावित कर सकते हैं। विवरण के लिए नोट को distinct() देखें distinct()
  • यदि आप एक extra() कॉल के बाद values() क्लॉज़ का उपयोग करते values() , तो extra() में select तर्क द्वारा परिभाषित कोई भी फ़ील्ड values() कॉल में स्पष्ट रूप से शामिल होना चाहिए। values() कॉल के बाद किए गए किसी भी extra() कॉल में इसके अतिरिक्त चयनित फ़ील्ड को अनदेखा किया जाएगा।
  • values() defer() बाद only() और defer() को कॉल defer() कोई मतलब नहीं है, इसलिए ऐसा करने से NotImplementedError
  • ट्रांसफ़ॉर्म और एग्रीगेट को मिलाने के लिए दो annotate() कॉल का उपयोग करने की आवश्यकता है, या तो स्पष्ट रूप से या values() लिए कीवर्ड तर्क के रूप में values() । ऊपर के रूप में, यदि ट्रांसफ़ॉर्मेशन को संबंधित फ़ील्ड पर पंजीकृत किया गया है तो पहले annotate() को छोड़ा जा सकता है, इस प्रकार निम्नलिखित विवरण निम्नलिखित हैं:

    >>> from django.db.models import CharField, Count
    >>> from django.db.models.functions import Lower
    >>> CharField.register_lookup(Lower)
    >>> Blog.objects.values('entry__authors__name__lower').annotate(entries=Count('entry'))
    <QuerySet [{'entry__authors__name__lower': 'test author', 'entries': 33}]>
    >>> Blog.objects.values(
    ...     entry__authors__name__lower=Lower('entry__authors__name')
    ... ).annotate(entries=Count('entry'))
    <QuerySet [{'entry__authors__name__lower': 'test author', 'entries': 33}]>
    >>> Blog.objects.annotate(
    ...     entry__authors__name__lower=Lower('entry__authors__name')
    ... ).values('entry__authors__name__lower').annotate(entries=Count('entry'))
    <QuerySet [{'entry__authors__name__lower': 'test author', 'entries': 33}]>
    

यह तब उपयोगी होता है जब आप जानते हैं कि आपको केवल कुछ उपलब्ध फ़ील्ड से मानों की आवश्यकता होती है और आपको किसी मॉडल इंस्टेंस ऑब्जेक्ट की कार्यक्षमता की आवश्यकता नहीं होगी। केवल उन फ़ील्ड्स का चयन करना अधिक कुशल है, जिनका आपको उपयोग करने की आवश्यकता है।

अंत में, ध्यान दें कि आप values() कॉल के बाद filter() , order_by() , आदि कॉल कर सकते हैं, इसका मतलब है कि ये दोनों कॉल समान हैं:

Blog.objects.values().order_by('id')
Blog.objects.order_by('id').values()

जिन लोगों ने Django बनाया, वे सभी SQL- प्रभावित करने वाले तरीकों को रखना पसंद करते हैं, किसी भी आउटपुट-प्रभावित तरीकों (जैसे values() बाद (वैकल्पिक रूप से), लेकिन यह वास्तव में मायने नहीं रखता है। यह वास्तव में आपके व्यक्तिवाद को भड़काने का मौका है।

आप OneToOneField , ForeignKey और OneToOneField विशेषताओं के माध्यम से संबंधित संबंधों के साथ संबंधित मॉडल पर फ़ील्ड का भी उल्लेख कर सकते हैं:

>>> Blog.objects.values('name', 'entry__headline')
<QuerySet [{'name': 'My blog', 'entry__headline': 'An entry'},
     {'name': 'My blog', 'entry__headline': 'Another entry'}, ...]>

चेतावनी

क्योंकि ManyToManyField विशेषताएँ और उल्टे संबंधों में कई संबंधित पंक्तियाँ हो सकती हैं, इनमें आपके परिणाम सेट के आकार पर गुणक प्रभाव हो सकता है। यह विशेष रूप से स्पष्ट किया जाएगा यदि आप अपने values() क्वेरी में कई ऐसे क्षेत्रों को शामिल करते values() , जिस स्थिति में सभी संभावित संयोजन वापस आ जाएंगे।

values_list()

values_list(*fields, flat=False, named=False)

यह values() समान है सिवाय इसके कि शब्दकोशों को वापस करने के बजाय, यह पुनरावृत्त होने पर ट्यूपल्स लौटाता है। प्रत्येक टपल में संबंधित फ़ील्ड या मान से मान शामिल होता है जो values_list() कॉल values_list() में पारित होते हैं - इसलिए पहला आइटम पहला फ़ील्ड है, उदाहरण के लिए:

>>> Entry.objects.values_list('id', 'headline')
<QuerySet [(1, 'First entry'), ...]>
>>> from django.db.models.functions import Lower
>>> Entry.objects.values_list('id', Lower('headline'))
<QuerySet [(1, 'first entry'), ...]>

यदि आप केवल एक ही क्षेत्र में पास होते हैं, तो आप flat पैरामीटर में भी पास हो सकते हैं। यदि True , तो इसका मतलब यह होगा कि लौटे परिणाम एक-ट्यूपल के बजाय एकल मान हैं। एक उदाहरण को अंतर स्पष्ट करना चाहिए:

>>> Entry.objects.values_list('id').order_by('id')
<QuerySet[(1,), (2,), (3,), ...]>

>>> Entry.objects.values_list('id', flat=True).order_by('id')
<QuerySet [1, 2, 3, ...]>

एक से अधिक क्षेत्र होने पर flat में पास होना एक त्रुटि है।

आप named=True रूप में परिणाम प्राप्त करने के लिए named=True पास कर सकते हैं:

>>> Entry.objects.values_list('id', 'headline', named=True)
<QuerySet [Row(id=1, headline='First entry'), ...]>

नामित ट्यूपल का उपयोग करने से परिणामों को अधिक पठनीय बनाया जा सकता है, परिणाम को नामांकित ट्यूपल में बदलने के लिए एक छोटे से प्रदर्शन दंड की कीमत पर।

यदि आप किसी भी मान को values_list() पास नहीं करते हैं, तो यह मॉडल के सभी क्षेत्रों को लौटा देगा, जिस क्रम में वे घोषित किए गए थे।

एक सामान्य आवश्यकता एक निश्चित मॉडल उदाहरण के विशिष्ट फ़ील्ड मान को प्राप्त करना है। इसे प्राप्त करने के लिए, एक get() कॉल के बाद values_list() उपयोग करें:

>>> Entry.objects.values_list('headline', flat=True).get(pk=1)
'First entry'

values() और values_list() दोनों एक विशिष्ट उपयोग मामले के लिए अनुकूलन के रूप में अभिप्रेत हैं: मॉडल उदाहरण बनाने के ओवरहेड के बिना डेटा का सबसेट पुनर्प्राप्त करना। यह रूपक तब अलग हो जाता है जब कई-से-कई और अन्य बहुस्तरीय संबंधों (जैसे कि एक रिवर्स विदेशी कुंजी के एक से कई संबंध) के साथ काम करते हैं क्योंकि "एक पंक्ति, एक वस्तु" धारणा धारण नहीं करती है।

उदाहरण के लिए, ManyToManyField क्वेरी करते समय व्यवहार पर ध्यान दें:

>>> Author.objects.values_list('name', 'entry__headline')
<QuerySet [('Noam Chomsky', 'Impressions of Gaza'),
 ('George Orwell', 'Why Socialists Do Not Believe in Fun'),
 ('George Orwell', 'In Defence of English Cooking'),
 ('Don Quixote', None)]>

कई प्रविष्टियों वाले लेखक कई बार दिखाई देते हैं और बिना प्रविष्टियों के लेखकों के पास प्रविष्टि शीर्षक के लिए None

इसी तरह, जब एक विदेशी विदेशी कुंजी को क्वेरी करते हैं, तो None भी लेखक नहीं होने वाली प्रविष्टियों के लिए प्रकट होता है:

>>> Entry.objects.values_list('authors')
<QuerySet [('Noam Chomsky',), ('George Orwell',), (None,)]>
Django 2.0 में बदला:

named पैरामीटर जोड़ा गया था।

dates()

dates(field, kind, order='ASC')

QuerySet की सामग्री के भीतर एक विशेष प्रकार की सभी उपलब्ध तारीखों का प्रतिनिधित्व करने वाली QuerySet एक सूची का मूल्यांकन करने वाली QuerySet को QuerySet

field आपके मॉडल का एक DateField का नाम होना चाहिए। kind या तो "year" , "month" , "week" , या "day" होनी चाहिए। परिणाम सूची में प्रत्येक datetime.date ऑब्जेक्ट दिए गए type लिए "छोटा" है।

  • "year" क्षेत्र के लिए सभी अलग-अलग वर्ष मानों की सूची देता है।
  • "month" क्षेत्र के लिए सभी अलग-अलग वर्ष / महीने के मूल्यों की एक सूची देता है।
  • "week" क्षेत्र के लिए सभी अलग-अलग वर्ष / सप्ताह मूल्यों की सूची देता है। सभी तिथियां सोमवार होंगी।
  • "day" क्षेत्र के लिए सभी अलग-अलग वर्ष / माह / दिन मूल्यों की एक सूची देता है।

order , जो 'ASC' चूक करता है, या तो 'ASC' या 'DESC' होना चाहिए। यह निर्दिष्ट करता है कि परिणाम कैसे ऑर्डर करें।

उदाहरण:

>>> Entry.objects.dates('pub_date', 'year')
[datetime.date(2005, 1, 1)]
>>> Entry.objects.dates('pub_date', 'month')
[datetime.date(2005, 2, 1), datetime.date(2005, 3, 1)]
>>> Entry.objects.dates('pub_date', 'week')
[datetime.date(2005, 2, 14), datetime.date(2005, 3, 14)]
>>> Entry.objects.dates('pub_date', 'day')
[datetime.date(2005, 2, 20), datetime.date(2005, 3, 20)]
>>> Entry.objects.dates('pub_date', 'day', order='DESC')
[datetime.date(2005, 3, 20), datetime.date(2005, 2, 20)]
>>> Entry.objects.filter(headline__contains='Lennon').dates('pub_date', 'day')
[datetime.date(2005, 3, 20)]
Django 2.1 में परिवर्तित:

"सप्ताह" समर्थन जोड़ा गया था।

datetimes()

datetimes(field_name, kind, order='ASC', tzinfo=None)

QuerySet की सामग्री के भीतर एक विशेष प्रकार की सभी उपलब्ध तिथियों का प्रतिनिधित्व करने वाले QuerySet ऑब्जेक्ट्स की सूची का मूल्यांकन करता है जो एक QuerySet

field_name आपके मॉडल के DateTimeField का नाम होना चाहिए।

kind या तो "year" , "month" , "week" , "day" , "hour" , "minute" , या "second" । परिणाम सूची में प्रत्येक datetime.datetime ऑब्जेक्ट दिए गए type लिए "छोटा" है।

order , जो 'ASC' चूक करता है, या तो 'ASC' या 'DESC' होना चाहिए। यह निर्दिष्ट करता है कि परिणाम कैसे ऑर्डर करें।

tzinfo टाइम ज़ोन को परिभाषित करता है जिसमें tzinfo को परिवर्तित किया जाता है। वास्तव में, दिए गए डेटाइम के उपयोग में समय क्षेत्र के आधार पर अलग-अलग प्रतिनिधित्व होते हैं। यह पैरामीटर एक datetime.tzinfo ऑब्जेक्ट होना चाहिए। यदि यह None , तो Django वर्तमान समय क्षेत्र का उपयोग करता है। USE_TZ के False होने पर USE_TZ कोई प्रभाव नहीं पड़ता है।

Django 2.1 में परिवर्तित:

"सप्ताह" समर्थन जोड़ा गया था।

ध्यान दें

यह फ़ंक्शन डेटाबेस में सीधे समय क्षेत्र रूपांतरण करता है। परिणामस्वरूप, आपका डेटाबेस tzinfo.tzname(None) के मूल्य की व्याख्या करने में सक्षम होना चाहिए। यह निम्नलिखित आवश्यकताओं में अनुवाद करता है:

  • SQLite: कोई आवश्यकताओं। पायथन के साथ पाइथन में रूपांतरण किए जाते हैं (जब आप Django स्थापित करते हैं)।
  • PostgreSQL: कोई आवश्यकता नहीं ( टाइम ज़ोन देखें)।
  • ओरेकल: कोई आवश्यकता नहीं ( टाइम ज़ोन फ़ाइल चुनना )।
  • MySQL: mysql_tzinfo_to_sql साथ समय क्षेत्र तालिकाएँ लोड करें।

none()

none()

कॉलिंग नॉट () से एक क्वेरीसेट बनेगी जो कभी भी किसी ऑब्जेक्ट को नहीं लौटाती है और परिणामों को एक्सेस करते समय किसी भी क्वेरी को निष्पादित नहीं किया जाएगा। एक qs.none () क्वेरीसेट EmptyQuerySet का एक उदाहरण है।

उदाहरण:

>>> Entry.objects.none()
<QuerySet []>
>>> from django.db.models.query import EmptyQuerySet
>>> isinstance(Entry.objects.none(), EmptyQuerySet)
True

all()

all()

वर्तमान QuerySet (या QuerySet उपवर्ग) की एक प्रति लौटाता है। यह उन स्थितियों में उपयोगी हो सकता है जहां आप एक मॉडल प्रबंधक या एक QuerySet पास QuerySet और परिणाम पर आगे फ़िल्टरिंग कर सकते हैं। किसी भी ऑब्जेक्ट पर all() कॉल all() बाद, आपके पास निश्चित रूप से साथ काम करने के लिए एक QuerySet होगी।

जब एक QuerySet का evaluated जाता evaluated , तो यह आम तौर पर इसके परिणामों को कैश करता है। यदि किसी QuerySet मूल्यांकन के बाद डेटाबेस में डेटा परिवर्तित हो सकता है, तो आप पहले से मूल्यांकन किए गए QuerySet पर all() कॉल करके एक ही क्वेरी के लिए अद्यतन परिणाम प्राप्त कर सकते हैं।

union()

union(*other_qs, all=False)

दो या अधिक QuerySet के परिणामों को संयोजित करने के लिए SQL के UNION ऑपरेटर का उपयोग करता है। उदाहरण के लिए:

>>> qs1.union(qs2, qs3)

UNION ऑपरेटर डिफ़ॉल्ट रूप से केवल भिन्न मानों का चयन करता है। डुप्लिकेट मानों की अनुमति देने के लिए, all=True तर्क का उपयोग करें।

union() , intersection() , और difference() रिटर्न मॉडल उदाहरणों के प्रकार के पहले QuerySet भले ही तर्क अन्य मॉडल के QuerySet हैं। अलग-अलग मॉडल पास करना तब तक काम करता है जब तक SELECT लिस्ट सभी QuerySet s (कम से कम प्रकारों में एक समान क्रम में टाइप के रूप में लंबे समय तक मायने नहीं QuerySet ) में समान है। ऐसे मामलों में, आपको पहले QuerySet से कॉलम नाम का उपयोग करना होगा जिसके परिणामस्वरूप QuerySet लागू किया QuerySet । उदाहरण के लिए:

>>> qs1 = Author.objects.values_list('name')
>>> qs2 = Entry.objects.values_list('headline')
>>> qs1.union(qs2).order_by('name')

इसके अलावा, केवल LIMIT , OFFSET , COUNT(*) , ORDER BY , और निर्दिष्ट कॉलम (यानी स्लाइसिंग, count() , order_by() , और values() / values_list() ) परिणामी QuerySet पर QuerySet । इसके अलावा, डेटाबेस उन प्रश्नों पर प्रतिबंध लगाते हैं जिन्हें संयुक्त प्रश्नों में संचालन की अनुमति है। उदाहरण के लिए, अधिकांश डेटाबेस संयुक्त प्रश्नों में LIMIT या OFFSET अनुमति नहीं देते हैं।

intersection()

intersection(*other_qs)

दो या अधिक QuerySet के साझा तत्वों को वापस करने के लिए SQL के INTERSECT ऑपरेटर का उपयोग करता है। उदाहरण के लिए:

>>> qs1.intersection(qs2, qs3)

कुछ प्रतिबंधों के लिए union() देखें।

difference()

difference(*other_qs)

SQL के QuerySet ऑपरेटर का उपयोग केवल QuerySet में मौजूद तत्वों को रखने के लिए QuerySet लेकिन कुछ अन्य QuerySet s में नहीं। उदाहरण के लिए:

>>> qs1.difference(qs2, qs3)

कुछ प्रतिबंधों के लिए union() देखें।

एक QuerySet लौटाता है जो विदेशी-कुंजी रिश्तों का "अनुसरण" करेगा, जब यह अपनी क्वेरी को निष्पादित करता है तो अतिरिक्त संबंधित वस्तु डेटा का चयन करेगा। यह एक प्रदर्शन बूस्टर है जिसके परिणामस्वरूप एक और अधिक जटिल क्वेरी होती है लेकिन बाद में विदेशी-कुंजी रिश्तों के उपयोग के लिए डेटाबेस प्रश्नों की आवश्यकता नहीं होगी।

निम्नलिखित उदाहरण सादे लुकअप और select_related() लुकअप के बीच अंतर को दर्शाते हैं। यहाँ मानक खोज है:

# Hits the database.
e = Entry.objects.get(id=5)

# Hits the database again to get the related Blog object.
b = e.blog

और यहां select_related लुकअप:

# Hits the database.
e = Entry.objects.select_related('blog').get(id=5)

# Doesn't hit the database, because e.blog has been prepopulated
# in the previous query.
b = e.blog

आप ऑब्जेक्ट के किसी भी select_related() साथ select_related() उपयोग कर सकते हैं:

from django.utils import timezone

# Find all the blogs with entries scheduled to be published in the future.
blogs = set()

for e in Entry.objects.filter(pub_date__gt=timezone.now()).select_related('blog'):
    # Without select_related(), this would make a database query for each
    # loop iteration in order to fetch the related blog for each entry.
    blogs.add(e.blog)

के क्रम filter() और select_related() जंजीरों महत्वपूर्ण नहीं है। ये क्वेरी समतुल्य हैं:

Entry.objects.filter(pub_date__gt=timezone.now()).select_related('blog')
Entry.objects.select_related('blog').filter(pub_date__gt=timezone.now())

आप उन्हें क्वेरी करने के लिए इसी तरह से विदेशी कुंजियों का पालन कर सकते हैं। यदि आपके पास निम्नलिखित मॉडल हैं:

from django.db import models

class City(models.Model):
    # ...
    pass

class Person(models.Model):
    # ...
    hometown = models.ForeignKey(
        City,
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
    )

class Book(models.Model):
    # ...
    author = models.ForeignKey(Person, on_delete=models.CASCADE)

... तो एक फोन करने के लिए Book.objects.select_related('author__hometown').get(id=4) कैश होगा संबंधित Person और संबंधित City :

# Hits the database with joins to the author and hometown tables.
b = Book.objects.select_related('author__hometown').get(id=4)
p = b.author         # Doesn't hit the database.
c = p.hometown       # Doesn't hit the database.

# Without select_related()...
b = Book.objects.get(id=4)  # Hits the database.
p = b.author         # Hits the database.
c = p.hometown       # Hits the database.

आप पास किए गए फ़ील्ड की सूची में किसी भी ForeignKey या OneToOneField संबंध का उल्लेख कर सकते हैं select_related()

आप OneToOneField पास किए गए फ़ील्ड की सूची में एक की उल्टी दिशा को भी संदर्भित कर सकते हैं select_related - अर्थात्, आप OneToOneField उस ऑब्जेक्ट पर वापस आ सकते हैं जिस पर फ़ील्ड परिभाषित है। फ़ील्ड नाम निर्दिष्ट करने के बजाय, related_name संबंधित ऑब्जेक्ट पर फ़ील्ड के लिए उपयोग करें ।

ऐसी कुछ परिस्थितियाँ हो सकती हैं जहाँ आप select_related() बहुत सारी संबंधित वस्तुओं के साथ कॉल करना चाहते हैं, या जहाँ आप सभी संबंधों को नहीं जानते हैं। इन मामलों में select_related() बिना किसी तर्क के कॉल करना संभव है । यह सभी गैर-अशक्त विदेशी कुंजियों का अनुसरण करेगा जो इसे पा सकती हैं - अशक्त विदेशी कुंजियों को निर्दिष्ट किया जाना चाहिए। यह ज्यादातर मामलों में अनुशंसित नहीं है क्योंकि यह अंतर्निहित क्वेरी को अधिक जटिल बनाने और अधिक डेटा वापस करने की संभावना है, वास्तव में आवश्यक है।

आप के पिछले कॉल से जोड़ा संबंधित क्षेत्रों की सूची स्पष्ट करने की जरूरत है select_related एक पर QuerySet , आप पास कर सकते हैं None एक पैरामीटर के रूप:

>>> without_relations = queryset.select_related(None)

चेनिंग select_related कि है कि - कॉल अन्य तरीकों के लिए एक समान तरीके से काम करता है select_related('foo', 'bar') के बराबर है select_related('foo').select_related('bar')

एक रिटर्न QuerySet जो स्वचालित रूप से प्राप्त होगा, एक एकल बैच में, प्रत्येक निर्दिष्ट लुकअप के लिए संबंधित ऑब्जेक्ट।

इसका एक समान उद्देश्य है select_related , जिसमें दोनों को संबंधित प्रश्नों तक पहुँचने के कारण उत्पन्न होने वाले डेटाबेस प्रश्नों के प्रलय को रोकने के लिए डिज़ाइन किया गया है, लेकिन रणनीति काफी अलग है।

select_related एक SQL जॉइन और संबंधित ऑब्जेक्ट के फील्ड को SELECT स्टेटमेंट में शामिल करके काम करता है । इस कारण से, select_related संबंधित ऑब्जेक्ट को समान डेटाबेस क्वेरी में मिलता है। हालांकि, बहुत बड़े परिणाम सेट से बचने के लिए जो 'कई' संबंधों में शामिल होने से परिणाम देगा, select_related केवल एकल-मूल्यवान रिश्तों तक सीमित है - विदेशी कुंजी और वन-टू-वन।

prefetch_related दूसरी ओर, प्रत्येक रिश्ते के लिए एक अलग खोज करता है, और पायथन में 'जॉइनिंग' करता है। यह कई select_related कुंजी और कई-से-एक ऑब्जेक्ट को प्रीफ़ैच करने की अनुमति देता है, जिसका उपयोग विदेशी कुंजी और एक-से-एक रिश्तों के अलावा, जो कि समर्थित हैं, का उपयोग करके नहीं किया जा सकता है select_related । यह भी प्रीफ़ेटिंग का समर्थन करता है GenericRelation और GenericForeignKey , हालांकि, इसे परिणामों के एक सजातीय सेट तक सीमित होना चाहिए। उदाहरण के लिए, पूर्वनिर्धारित वस्तुओं द्वारा संदर्भित एक GenericForeignKey ही समर्थित है यदि क्वेरी एक तक सीमित है ContentType

उदाहरण के लिए, मान लीजिए कि आपके पास ये मॉडल हैं:

from django.db import models

class Topping(models.Model):
    name = models.CharField(max_length=30)

class Pizza(models.Model):
    name = models.CharField(max_length=50)
    toppings = models.ManyToManyField(Topping)

    def __str__(self):
        return "%s (%s)" % (
            self.name,
            ", ".join(topping.name for topping in self.toppings.all()),
        )

और भाग खड़ा हुआ:

>>> Pizza.objects.all()
["Hawaiian (ham, pineapple)", "Seafood (prawns, smoked salmon)"...

इस के साथ समस्या यह है कि हर बार है Pizza.__str__() पूछता है के लिए self.toppings.all() यह डेटाबेस क्वेरी करने के लिए है, तो Pizza.objects.all() के लिए टॉपिंग मेज पर एक प्रश्न चलेंगे हर पिज्जा में आइटम QuerySet

हम केवल दो प्रश्नों का उपयोग करके कम कर सकते हैं prefetch_related :

>>> Pizza.objects.all().prefetch_related('toppings')

यह self.toppings.all() प्रत्येक के लिए तात्पर्य है Pizza ; अब हर बार self.toppings.all() कॉल किया जाता है, आइटम के लिए डेटाबेस में जाने के बजाय, यह उन्हें प्रीफ़ेट किए गए QuerySet कैश में मिलेगा जो एक ही क्वेरी में पॉपुलेटेड था।

यही है, सभी प्रासंगिक टॉपिंग को एक ही क्वेरी में प्राप्त किया जाएगा, और इसका उपयोग QuerySets प्रासंगिक परिणामों के पहले से भरे हुए कैश के लिए किया जाएगा; ये QuerySets तब self.toppings.all() कॉल में उपयोग किए जाते हैं।

मूल्यांकन prefetch_related() किए जाने के बाद QuerySet शुरू की गई अतिरिक्त क्वेरी का मूल्यांकन किया गया है और प्राथमिक क्वेरी निष्पादित की गई है।

यदि आपके पास मॉडल इंस्टेंसेस के चलने योग्य हैं, तो आप prefetch_related_objects() फ़ंक्शन का उपयोग करके उन इंस्टेंस पर संबंधित विशेषताओं को प्रीफ़ैच कर सकते हैं ।

ध्यान दें कि प्राथमिक QuerySet और सभी निर्दिष्ट संबंधित वस्तुओं का परिणाम कैश तब पूरी तरह से मेमोरी में लोड हो जाएगा। यह सामान्य व्यवहार को बदल देता है QuerySets , जो आम तौर पर सभी वस्तुओं को मेमोरी में लोड करने से बचने की कोशिश करते हैं, इससे पहले कि वे डेटाबेस में एक क्वेरी निष्पादित होने के बाद भी आवश्यक हो।

ध्यान दें

याद रखें कि, हमेशा की तरह QuerySets , किसी भी बाद में जंजीर के तरीके जो कि एक अलग डेटाबेस क्वेरी का अर्थ है पहले कैश्ड परिणामों को अनदेखा करेंगे, और एक नए डेटाबेस क्वेरी का उपयोग करके डेटा पुनर्प्राप्त करेंगे। तो, यदि आप निम्नलिखित लिखते हैं:

>>> pizzas = Pizza.objects.prefetch_related('toppings')
>>> [list(pizza.toppings.filter(spicy=True)) for pizza in pizzas]

... तो जो तथ्य pizza.toppings.all() पहले से बताए गए हैं वे आपकी मदद नहीं करेंगे। prefetch_related('toppings') निहित pizza.toppings.all() है, लेकिन pizza.toppings.filter() एक नया और अलग क्वेरी है। पूर्वनिर्मित कैश यहां मदद नहीं कर सकता; वास्तव में यह प्रदर्शन को नुकसान पहुंचाता है, क्योंकि आपने एक डेटाबेस क्वेरी की है जिसका आपने उपयोग नहीं किया है। इसलिए सावधानी के साथ इस सुविधा का उपयोग करें!

इसके अलावा, यदि आप डेटाबेस-परिवर्तन करने वाले तरीकों add() को कहते हैं remove() , clear() या set() , related managers संबंध के लिए किसी भी पूर्वनिर्मित कैश को मंजूरी दे दी जाएगी।

आप संबंधित फ़ील्ड के संबंधित फ़ील्ड को करने के लिए सामान्य ज्वाइन सिंटैक्स का भी उपयोग कर सकते हैं। मान लीजिए कि हमारे पास उपरोक्त उदाहरण के लिए एक अतिरिक्त मॉडल है:

class Restaurant(models.Model):
    pizzas = models.ManyToManyField(Pizza, related_name='restaurants')
    best_pizza = models.ForeignKey(Pizza, related_name='championed_by', on_delete=models.CASCADE)

निम्नलिखित सभी कानूनी हैं:

>>> Restaurant.objects.prefetch_related('pizzas__toppings')

यह रेस्तरां से संबंधित सभी पिज्जा और उन पिज्जा से संबंधित सभी टॉपिंग को प्रीफ़ैच करेगा। यह कुल 3 डेटाबेस प्रश्नों का परिणाम देगा - एक रेस्तरां के लिए, एक पिज्जा के लिए, और एक टॉपिंग के लिए।

>>> Restaurant.objects.prefetch_related('best_pizza__toppings')

यह प्रत्येक रेस्तरां के लिए सर्वश्रेष्ठ पिज्जा के लिए सबसे अच्छा पिज्जा और सभी टॉपिंग लाएगा। यह 3 डेटाबेस प्रश्नों में किया जाएगा - एक रेस्तरां के लिए, एक 'सर्वश्रेष्ठ पिज्जा' के लिए, और एक टॉपिंग के लिए।

बेशक, क्वेरी की संख्या को 2 तक कम करने के लिए best_pizza संबंध का उपयोग select_related किया जा सकता है :

>>> Restaurant.objects.select_related('best_pizza').prefetch_related('best_pizza__toppings')

चूँकि मुख्य क्वेरी के बाद प्रीफ़ैच को निष्पादित किया जाता है (जिसमें इसमें शामिल होने की आवश्यकता होती है select_related ), यह पता लगाने में सक्षम है कि best_pizza ऑब्जेक्ट पहले से ही लाए गए हैं, और यह उन्हें फिर से लाना छोड़ देगा।

prefetch_related कॉलिंग कॉल प्रीफ़ेट किए गए लुकअप को संचित करेगा। किसी भी prefetch_related व्यवहार को साफ़ करने के लिए , None एक पैरामीटर के रूप में पास करें :

>>> non_prefetched = qs.prefetch_related(None)

उपयोग करते समय ध्यान देने योग्य एक अंतर यह prefetch_related है कि एक क्वेरी द्वारा बनाई गई वस्तुओं को विभिन्न वस्तुओं के बीच साझा किया जा सकता है जो कि वे संबंधित हैं अर्थात एक एकल पायथन मॉडल उदाहरण वस्तुओं के पेड़ में एक से अधिक बिंदुओं पर दिखाई दे सकता है जो वापस आ गए हैं। यह आमतौर पर विदेशी प्रमुख संबंधों के साथ होगा। आमतौर पर यह व्यवहार एक समस्या नहीं होगी, और वास्तव में मेमोरी और सीपीयू समय दोनों को बचाएगा।

जबकि prefetch_related प्रीफ़ेचिंग GenericForeignKey संबंधों का समर्थन करता है , प्रश्नों की संख्या डेटा पर निर्भर करेगी। चूंकि GenericForeignKey डेटा को कई तालिकाओं में संदर्भित किया जा सकता है, इसलिए सभी मदों के लिए एक क्वेरी के बजाय संदर्भित प्रति तालिका एक क्वेरी की आवश्यकता है। ContentType यदि प्रासंगिक पंक्तियों को पहले ही नहीं लाया गया है, तो तालिका पर अतिरिक्त प्रश्न हो सकते हैं ।

prefetch_related ज्यादातर मामलों में 'IN' ऑपरेटर का उपयोग करने वाले SQL क्वेरी का उपयोग करके लागू किया जाएगा। इसका अर्थ यह है कि QuerySet एक बड़े 'IN' क्लॉज को उत्पन्न किया जा सकता है, जो डेटाबेस पर निर्भर करता है, जब SQL क्वेरी को पार्स करने या निष्पादित करने की बात आती है, तो इसकी स्वयं की प्रदर्शन समस्याएं हो सकती हैं। हमेशा अपने उपयोग के मामले के लिए प्रोफ़ाइल!

ध्यान दें कि यदि आप iterator() क्वेरी को चलाने के लिए उपयोग करते हैं, तो prefetch_related() कॉल को नजरअंदाज कर दिया जाएगा क्योंकि ये दोनों अनुकूलन एक साथ नहीं होते हैं।

Prefetch प्रीफ़च ऑपरेशन को और नियंत्रित करने के लिए आप ऑब्जेक्ट का उपयोग कर सकते हैं ।

अपने सरलतम रूप Prefetch में पारंपरिक स्ट्रिंग आधारित लुक्स के बराबर है:

>>> from django.db.models import Prefetch
>>> Restaurant.objects.prefetch_related(Prefetch('pizzas__toppings'))

आप वैकल्पिक queryset तर्क के साथ एक कस्टम क्वेरीसेट प्रदान कर सकते हैं । इसका उपयोग क्वेरीसेट के डिफ़ॉल्ट ऑर्डर को बदलने के लिए किया जा सकता है:

>>> Restaurant.objects.prefetch_related(
...     Prefetch('pizzas__toppings', queryset=Toppings.objects.order_by('name')))

या select_related() आगे भी प्रश्नों की संख्या कम करने के लिए लागू होने पर कॉल करने के लिए:

>>> Pizza.objects.prefetch_related(
...     Prefetch('restaurants', queryset=Restaurant.objects.select_related('best_pizza')))

आप वैकल्पिक to_attr तर्क के साथ प्रीफ़ेट किए गए परिणाम को एक कस्टम विशेषता को भी असाइन कर सकते हैं । परिणाम सीधे एक सूची में संग्रहीत किया जाएगा।

यह एक ही संबंध को एक अलग के साथ कई बार प्रीफ़ैच करने की अनुमति देता है QuerySet ; उदाहरण के लिए:

>>> vegetarian_pizzas = Pizza.objects.filter(vegetarian=True)
>>> Restaurant.objects.prefetch_related(
...     Prefetch('pizzas', to_attr='menu'),
...     Prefetch('pizzas', queryset=vegetarian_pizzas, to_attr='vegetarian_menu'))

कस्टम के साथ बनाया to_attr गया लुकअप अभी भी अन्य लुकअप द्वारा हमेशा की तरह ट्रैवर्स किया जा सकता है:

>>> vegetarian_pizzas = Pizza.objects.filter(vegetarian=True)
>>> Restaurant.objects.prefetch_related(
...     Prefetch('pizzas', queryset=vegetarian_pizzas, to_attr='vegetarian_menu'),
...     'vegetarian_menu__toppings')

to_attr प्रीफ़ैच परिणाम को फ़िल्टर करते समय उपयोग करने की अनुशंसा की जाती है, क्योंकि यह संबंधित बैंकिंग कैश में फ़िल्टर किए गए परिणाम को संग्रहीत करने की तुलना में कम अस्पष्ट है:

>>> queryset = Pizza.objects.filter(vegetarian=True)
>>>
>>> # Recommended:
>>> restaurants = Restaurant.objects.prefetch_related(
...     Prefetch('pizzas', queryset=queryset, to_attr='vegetarian_pizzas'))
>>> vegetarian_pizzas = restaurants[0].vegetarian_pizzas
>>>
>>> # Not recommended:
>>> restaurants = Restaurant.objects.prefetch_related(
...     Prefetch('pizzas', queryset=queryset))
>>> vegetarian_pizzas = restaurants[0].pizzas.all()

कस्टम प्रीफ़ैचिंग एकल संबंधित संबंधों जैसे कि आगे ForeignKey या के साथ भी काम करता है OneToOneField । आम तौर पर आप select_related() इन संबंधों के लिए उपयोग करना चाहते हैं , लेकिन ऐसे कई मामले हैं जहां एक कस्टम के साथ प्रीफ़ैचिंग QuerySet उपयोगी है:

  • आप QuerySet उस मॉडल का उपयोग करना चाहते हैं जो संबंधित मॉडल पर आगे प्रीफ़ेटिंग करता है।
  • आप संबंधित वस्तुओं के केवल सबसेट को प्रीफ़ैच करना चाहते हैं।
  • आप प्रदर्शन अनुकूलन तकनीकों का उपयोग करना चाहते हैं जैसे defer() :

    >>> queryset = Pizza.objects.only('name')
    >>>
    >>> restaurants = Restaurant.objects.prefetch_related(
    ...     Prefetch('best_pizza', queryset=queryset))
    

ध्यान दें

लुकअप का क्रम मायने रखता है।

निम्नलिखित उदाहरण लें:

>>> prefetch_related('pizzas__toppings', 'pizzas')

यह तब भी काम करता है, जब यह अनियंत्रित हो, क्योंकि 'pizzas__toppings' पहले से ही सभी आवश्यक जानकारी शामिल हैं, इसलिए दूसरा तर्क 'pizzas' वास्तव में बेमानी है।

>>> prefetch_related('pizzas__toppings', Prefetch('pizzas', queryset=Pizza.objects.all()))

यह ValueError पहले से देखे गए लुकअप की क्वेरी को फिर से परिभाषित करने के प्रयास के कारण बढ़ेगा । ध्यान दें कि लुकअप के 'pizzas' हिस्से के रूप में ट्रैवर्स करने के लिए एक अंतर्निहित क्वेरीसेट बनाया गया था 'pizzas__toppings'

>>> prefetch_related('pizza_list__toppings', Prefetch('pizzas', to_attr='pizza_list'))

यह तब ट्रिगर होगा AttributeError क्योंकि संसाधित होने पर 'pizza_list' अभी तक मौजूद नहीं 'pizza_list__toppings' है।

यह विचार Prefetch वस्तुओं के उपयोग तक सीमित नहीं है । कुछ उन्नत तकनीकों की आवश्यकता हो सकती है कि अतिरिक्त प्रश्न बनाने से बचने के लिए लुकअप को एक विशिष्ट क्रम में किया जाए; इसलिए हमेशा prefetch_related तर्कों को ध्यान से आदेश देने की सिफारिश की जाती है ।

extra()

extra(select=None, where=None, params=None, tables=None, order_by=None, select_params=None)

कभी-कभी, Django क्वेरी सिंटैक्स अपने आप में एक जटिल WHERE क्लॉज को आसानी से व्यक्त नहीं कर सकता है । इन एज मामलों के लिए, Django extra() QuerySet संशोधक प्रदान करता है - एस द्वारा उत्पन्न एसक्यूएल में विशिष्ट खंडों को इंजेक्ट करने के लिए एक हुक QuerySet

इस उपाय को अंतिम उपाय के रूप में प्रयोग करें

यह एक पुराना API है जिसका लक्ष्य भविष्य में किसी बिंदु पर पदावनत करना है। इसका उपयोग केवल तभी करें जब आप अन्य क्वेरी विधियों का उपयोग करके अपनी क्वेरी को व्यक्त नहीं कर सकते। यदि आपको इसका उपयोग करने की आवश्यकता है, तो कृपया अपने उपयोग के मामले के साथ QuerySet.extra कीवर्ड का उपयोग करके एक टिकट दर्ज करें (कृपया पहले टिकटों की सूची की जांच करें) ताकि हम हटाने की अनुमति देने के लिए क्वेरीसैट एपीआई बढ़ा सकें । हम अब इस विधि के लिए बग्स को सुधार या ठीक नहीं कर रहे हैं। extra()

उदाहरण के लिए, इसका उपयोग extra() :

>>> qs.extra(
...     select={'val': "select col from sometable where othercol = %s"},
...     select_params=(someparam,),
... )

के बराबर है:

>>> qs.annotate(val=RawSQL("select col from sometable where othercol = %s", (someparam,)))

उपयोग करने RawSQL का मुख्य लाभ यह है कि output_field यदि आवश्यक हो तो आप सेट कर सकते हैं । मुख्य नकारात्मक पक्ष यह है कि यदि आप कच्ची एसक्यूएल में क्वेरी के कुछ तालिका उपनाम का उल्लेख करते हैं, तो यह संभव है कि Django उस एलियास को बदल सकता है (उदाहरण के लिए, जब क्वेरी को अभी तक किसी अन्य क्वेरी में एक उप-वर्ग के रूप में उपयोग किया जाता है)।

चेतावनी

जब भी आप उपयोग करें तो आपको बहुत सावधान रहना चाहिए extra() । हर बार जब आप इसका उपयोग करते हैं, तो आपको किसी भी पैरामीटर से बचना चाहिए जिसे उपयोगकर्ता params SQL इंजेक्शन के हमलों से बचाने के लिए उपयोग कर नियंत्रित कर सकता है ।

आपको SQL स्ट्रिंग में प्लेसहोल्डर्स को भी उद्धृत नहीं करना चाहिए। यह उदाहरण SQL इंजेक्शन के आसपास के उद्धरणों के कारण असुरक्षित है %s :

"select col from sometable where othercol = '%s'"  # unsafe!

आप और अधिक पढ़ सकते हैं कि Django की SQL इंजेक्शन सुरक्षा कैसे काम करती है।

परिभाषा के अनुसार, ये अतिरिक्त लुकअप विभिन्न डेटाबेस इंजनों के लिए पोर्टेबल नहीं हो सकते हैं (क्योंकि आप स्पष्ट रूप से SQL कोड लिख रहे हैं) और DRY सिद्धांत का उल्लंघन करते हैं, इसलिए यदि संभव हो तो आपको इनसे बचना चाहिए।

एक या अधिक निर्दिष्ट करें params , select , where या tables । किसी भी तर्क की आवश्यकता नहीं है, लेकिन आपको उनमें से कम से कम एक का उपयोग करना चाहिए।

  • select

    select तर्क आप में अतिरिक्त क्षेत्रों डाल सकते हैं SELECT खंड। यह उस विशेषता की गणना करने के लिए उपयोग करने के लिए SQL क्लॉस के लिए एक शब्दकोश मानचित्रण विशेषता नाम होना चाहिए।

    उदाहरण:

    Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})
    

    नतीजतन, प्रत्येक Entry ऑब्जेक्ट में एक अतिरिक्त विशेषता होगी is_recent , एक बूलियन जो यह दर्शाता है कि प्रविष्टि pub_date 1 जनवरी 2006 से अधिक है या नहीं।

    Django दिए गए SQL स्निपेट को सीधे SELECT स्टेटमेंट में सम्मिलित करता है , इसलिए उपरोक्त उदाहरण के परिणामस्वरूप SQL कुछ इस तरह होगा:

    SELECT blog_entry.*, (pub_date > '2006-01-01') AS is_recent
    FROM blog_entry;
    

    अगला उदाहरण अधिक उन्नत है; यह प्रत्येक परिणामी Blog वस्तु को एक entry_count विशेषता देने के लिए एक उपकुंजी करता है , संबंधित Entry वस्तुओं की एक पूर्णांक गणना :

    Blog.objects.extra(
        select={
            'entry_count': 'SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id'
        },
    )
    

    इस विशेष मामले में, हम इस तथ्य का फायदा उठा रहे हैं कि क्वेरी में पहले से ही blog_blog इसके FROM खंड में तालिका होगी ।

    उपरोक्त उदाहरण के परिणामस्वरूप SQL होगा:

    SELECT blog_blog.*, (SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id) AS entry_count
    FROM blog_blog;
    

    ध्यान दें कि उप-क्षेत्रों के आसपास अधिकांश डेटाबेस इंजनों के लिए आवश्यक कोष्ठकों को Django के select खंडों में आवश्यक नहीं है । यह भी ध्यान दें कि कुछ डेटाबेस बैकएंड, जैसे कुछ MySQL संस्करण, उपश्रेणियों का समर्थन नहीं करते हैं।

    कुछ दुर्लभ मामलों में, आप SQL अंशों में पैरामीटर पारित करना चाह सकते हैं extra(select=...) । इस उद्देश्य के लिए, select_params पैरामीटर का उपयोग करें । चूंकि select_params एक अनुक्रम है और select विशेषता एक शब्दकोश है, इसलिए कुछ देखभाल की आवश्यकता होती है ताकि मापदंडों को अतिरिक्त चुनिंदा टुकड़ों के साथ सही ढंग से मिलान किया जाए। इस स्थिति में, आपको मूल्य के collections.OrderedDict लिए उपयोग करना चाहिए select , न कि केवल एक सामान्य पायथन शब्दकोश।

    यह काम करेगा, उदाहरण के लिए:

    Blog.objects.extra(
        select=OrderedDict([('a', '%s'), ('b', '%s')]),
        select_params=('one', 'two'))
    

    यदि आपको %s अपने चयनित स्ट्रिंग के अंदर एक शाब्दिक उपयोग करने की आवश्यकता है , तो अनुक्रम का उपयोग करें %%s

  • where / tables

    आप स्पष्ट एसक्यूएल WHERE खंड को परिभाषित कर सकते हैं - शायद गैर-स्पष्ट कार्य करने के लिए - का उपयोग करके where । आप मैन्युअल रूप FROM से उपयोग करके SQL क्लॉज में टेबल जोड़ सकते हैं tables

    where और tables दोनों तार की एक सूची लेते हैं। सभी where पैरामीटर किसी भी अन्य खोज मापदंड के लिए "और" एड हैं।

    उदाहरण:

    Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
    

    … निम्नलिखित SQL में अनुवाद करता है (लगभग):

    SELECT * FROM blog_entry WHERE (foo='a' OR bar='a') AND (baz='a')
    

    tables पैरामीटर का उपयोग करते समय सावधान रहें यदि आप उन तालिकाओं को निर्दिष्ट कर रहे हैं जो पहले से ही क्वेरी में उपयोग किए जाते हैं। जब आप tables पैरामीटर के माध्यम से अतिरिक्त तालिकाओं को जोड़ते हैं , तो Django मान लेता है कि आप एक अतिरिक्त समय शामिल करना चाहते हैं, अगर यह पहले से ही शामिल है। यह एक समस्या पैदा करता है, क्योंकि तालिका नाम को फिर एक उपनाम दिया जाएगा। यदि एक SQL कथन में एक तालिका कई बार दिखाई देती है, तो दूसरी और बाद की घटनाओं को उपनाम का उपयोग करना चाहिए ताकि डेटाबेस उन्हें अलग बता सके। यदि आप अतिरिक्त तालिका में अतिरिक्त where पैरामीटर में जोड़ रहे हैं, तो यह त्रुटियों का कारण बनने वाला है।

    आम तौर पर आप केवल अतिरिक्त तालिकाओं को जोड़ेंगे जो पहले से ही क्वेरी में दिखाई नहीं देती हैं। हालाँकि, यदि ऊपर उल्लिखित मामला घटित होता है, तो कुछ समाधान हैं। पहले, देखें कि क्या आप अतिरिक्त तालिका को शामिल किए बिना प्राप्त कर सकते हैं और क्वेरी में पहले से ही उपयोग कर सकते हैं। यदि यह संभव नहीं है, तो अपने extra() कॉल को क्वेरीसेट निर्माण के सामने रखें ताकि आपकी तालिका उस तालिका का पहला उपयोग हो। अंत में, यदि अन्य सभी विफल हो जाते हैं, तो उत्पादित क्वेरी को देखें और where अपने अतिरिक्त तालिका में दिए गए उपनाम का उपयोग करने के लिए अपने जोड़ को फिर से लिखें। प्रत्येक बार जब आप क्वेरी को उसी तरीके से बनाते हैं, तो उपनाम एक ही होगा, इसलिए आप उपनाम को बदलने के लिए भरोसा नहीं कर सकते हैं।

  • order_by

    यदि आपको नए पैरामीटर या तालिकाओं में से कुछ का उपयोग करके परिणामी क्वेरी को ऑर्डर करने की आवश्यकता है, तो स्ट्रिंग के अनुक्रम में पैरामीटर का extra() उपयोग करें और पास करें। ये स्ट्रिंग्स या तो मॉडल फ़ील्ड होनी चाहिए (जैसे क्वेरी पर सामान्य विधि में), उस स्तंभ के लिए प्रपत्र या किसी अन्य के लिए जिसे आपने पैरामीटर में निर्दिष्ट किया था । order_by extra() order_by() table_name.column_name select extra()

    उदाहरण के लिए:

    q = Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})
    q = q.extra(order_by = ['-is_recent'])
    

    यह उन सभी वस्तुओं को क्रमबद्ध कर देगा जिनके is_recent लिए परिणाम सेट के सामने सच है ( एक अवरोही क्रम में True पहले False )।

    यह दिखाता है, वैसे, कि आप कई कॉल कर सकते हैं extra() और यह आपकी अपेक्षा के अनुसार व्यवहार करेगा (हर बार नए अवरोधों को जोड़ते हुए)।

  • params

    where पैरामीटर ऊपर बताई गई मानक अजगर डेटाबेस स्ट्रिंग प्लेसहोल्डर का उपयोग कर सकते हैं - '%s' मापदंडों डेटाबेस इंजिन को निर्देशित करने चाहिए स्वचालित रूप से बोली। params तर्क किसी भी अतिरिक्त पैरामीटर की एक सूची प्रतिस्थापित किया जा रहा है।

    उदाहरण:

    Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
    

    हमेशा params सीधे मानों को एम्बेड करने के बजाय उपयोग करें where क्योंकि params यह सुनिश्चित करेगा कि मान आपके विशेष बैकएंड के अनुसार सही रूप से उद्धृत किए गए हैं। उदाहरण के लिए, उद्धरण सही ढंग से बच जाएगा।

    खराब:

    Entry.objects.extra(where=["headline='Lennon'"])
    

    अच्छा:

    Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
    

चेतावनी

यदि आप MySQL पर क्वेरी कर रहे हैं, तो ध्यान दें कि टाइप करते समय MySQL का साइलेंट टाइप कॉर्शन अप्रत्याशित परिणाम दे सकता है। यदि आप एक स्ट्रिंग प्रकार के कॉलम पर क्वेरी करते हैं, लेकिन पूर्णांक मान के साथ, MySQL तुलना करने से पहले तालिका में सभी मानों के प्रकारों को एक पूर्णांक तक ले जाएगा। उदाहरण के लिए, यदि आपकी तालिका में मान हैं 'abc' , 'def' और आप क्वेरी करते हैं WHERE mycolumn=0 , तो दोनों पंक्तियाँ मेल खाएँगी। इसे रोकने के लिए, क्वेरी में मान का उपयोग करने से पहले सही टाइपकास्टिंग करें।

defer()

defer(*fields)

कुछ जटिल डेटा-मॉडलिंग स्थितियों में, आपके मॉडल में बहुत सारे फ़ील्ड हो सकते हैं, जिनमें से कुछ में बहुत सारे डेटा (उदाहरण के लिए, टेक्स्ट फ़ील्ड) हो सकते हैं, या उन्हें पायथन ऑब्जेक्ट्स में बदलने के लिए महंगी प्रसंस्करण की आवश्यकता हो सकती है। यदि आप किसी ऐसी स्थिति में क्वेरीसेट के परिणामों का उपयोग कर रहे हैं, जहां आपको नहीं पता है कि क्या आपको उन विशेष क्षेत्रों की आवश्यकता है जब आप शुरू में डेटा प्राप्त करते हैं, तो आप Django को डेटाबेस से उन्हें पुनर्प्राप्त नहीं करने के लिए कह सकते हैं।

यह उन क्षेत्रों के नामों को पारित करने के लिए किया जाता है, जिन्हें लोड नहीं करना है defer() :

Entry.objects.defer("headline", "body")

फ़ील्ड्स में आस्थगित किया गया एक क्वेरी अभी भी मॉडल इंस्टेंस को वापस करेगा। यदि आप उस फ़ील्ड तक पहुंचते हैं, तो प्रत्येक स्थगित क्षेत्र को डेटाबेस से पुनर्प्राप्त किया जाएगा (एक बार में सभी, एक बार में सभी स्थगित फ़ील्ड नहीं)।

आप कई कॉल कर सकते हैं defer() । प्रत्येक कॉल स्थगित फ़ील्ड में नए फ़ील्ड जोड़ता है:

# Defers both the body and headline fields.
Entry.objects.defer("body").filter(rating=5).defer("headline")

जिस क्षेत्र में आस्थगित सेट में फ़ील्ड जोड़े जाते हैं, वह कोई मायने नहीं रखता। defer() फ़ील्ड नाम के साथ कॉल करना जो पहले से ही स्थगित हो चुका है, हानिरहित है (फ़ील्ड अभी भी स्थगित हो जाएगी)।

आप संबंधित संबंधित क्षेत्रों में select_related() मानक डबल-अंडरस्कोर नोटेशन का उपयोग करके संबंधित मॉडल (यदि संबंधित मॉडल लोड कर रहे हैं ) में फ़ील्ड लोडिंग को अलग कर सकते हैं:

Blog.objects.select_related().defer("entry__headline", "entry__body")

यदि आप आस्थगित क्षेत्रों का सेट खाली करना चाहते हैं, तो None एक पैरामीटर के रूप में पास करें defer() :

# Load all fields immediately.
my_queryset.defer(None)

एक मॉडल में कुछ क्षेत्रों को स्थगित नहीं किया जाएगा, भले ही आप उनके लिए पूछें। आप प्राथमिक कुंजी के लोडिंग को कभी भी स्थगित नहीं कर सकते। यदि आप select_related() संबंधित मॉडलों को पुनः प्राप्त करने के लिए उपयोग कर रहे हैं , तो आपको उस क्षेत्र के लोडिंग को स्थगित नहीं करना चाहिए जो प्राथमिक मॉडल से संबंधित एक से जोड़ता है, ऐसा करने से त्रुटि उत्पन्न होगी।

ध्यान दें

defer() विधि (और उसके चचेरे भाई, only() नीचे दिए गए) केवल उन्नत उपयोग-मामले के लिए कर रहे हैं। जब आप अपने प्रश्नों का बारीकी से विश्लेषण कर लेते हैं और आपको जो जानकारी की आवश्यकता होती है उसे ठीक से समझ लेते हैं तो उन्होंने एक अनुकूलन प्रदान किया है और यह माप लिया है कि आपके लिए आवश्यक फ़ील्ड को लौटाने और मॉडल के लिए फ़ील्ड का पूरा सेट महत्वपूर्ण होगा।

यहां तक ​​कि अगर आपको लगता है कि आप उन्नत उपयोग के मामले में हैं, तो केवल डिफर () का उपयोग करें जब आप क्वेरी लोड समय पर नहीं कर सकते, तो निर्धारित करें कि आपको अतिरिक्त फ़ील्ड की आवश्यकता होगी या नहीं । यदि आप अक्सर अपने डेटा के किसी विशेष सबसेट को लोड कर रहे हैं और उपयोग कर रहे हैं, तो आप जो सबसे अच्छा विकल्प बना सकते हैं वह है अपने मॉडल को सामान्य करना और गैर-लोड किए गए डेटा को एक अलग मॉडल (और डेटाबेस टेबल) में डालना। यदि स्तंभों को किसी कारण से एक तालिका में रहना चाहिए , तो केवल उन फ़ील्ड्स के साथ एक मॉडल बनाएं Meta.managed = False ( managed attribute जिसमें प्रलेखन देखें ) जिसमें आपको सामान्य रूप से लोड करने और उपयोग करने की आवश्यकता होती है, जहां आप अन्यथा कॉल कर सकते हैं defer() । यह आपके कोड को पाठक के लिए अधिक स्पष्ट बनाता है, थोड़ा तेज होता है और पायथन प्रक्रिया में थोड़ी कम मेमोरी का उपभोग करता है।

उदाहरण के लिए, ये दोनों मॉडल एक ही अंतर्निहित डेटाबेस तालिका का उपयोग करते हैं:

class CommonlyUsedModel(models.Model):
    f1 = models.CharField(max_length=10)

    class Meta:
        managed = False
        db_table = 'app_largetable'

class ManagedModel(models.Model):
    f1 = models.CharField(max_length=10)
    f2 = models.CharField(max_length=10)

    class Meta:
        db_table = 'app_largetable'

# Two equivalent QuerySets:
CommonlyUsedModel.objects.all()
ManagedModel.objects.all().defer('f2')

यदि कई क्षेत्रों को मानव रहित मॉडल में डुप्लिकेट करने की आवश्यकता है, तो साझा फ़ील्ड के साथ एक अमूर्त मॉडल बनाना सबसे अच्छा हो सकता है और उसके बाद अमूर्त और प्रबंधित मॉडल सार मॉडल से विरासत में मिले हैं।

ध्यान दें

save() स्थगित क्षेत्रों के साथ उदाहरणों के लिए कॉल करते समय, केवल लोड किए गए फ़ील्ड सहेजे जाएंगे। save() अधिक जानकारी के लिए देखें।

only()

only(*fields)

only() विधि और अधिक या कम के विपरीत है defer() । आप इसे उन फ़ील्ड्स के साथ कहते हैं जिन्हें किसी मॉडल को प्राप्त करते समय स्थगित नहीं किया जाना चाहिए । यदि आपके पास एक मॉडल है जहां लगभग सभी क्षेत्रों को स्थगित करने की आवश्यकता है, तो फ़ील्ड only() के पूरक सेट को निर्दिष्ट करने के लिए सरल कोड का परिणाम हो सकता है।

मान लीजिए कि आपके पास खेतों के साथ एक मॉडल है name , age और biography । आस्थगित क्षेत्रों के संदर्भ में निम्नलिखित दो क्वेरी समान हैं:

Person.objects.defer("age", "biography")
Person.objects.only("name")

जब भी आप only() इसे कहते हैं तो तुरंत लोड करने के लिए फ़ील्ड के सेट को बदल देता है। विधि का नाम महामारी है: केवल उन क्षेत्रों को तुरंत लोड किया जाता है; शेष सुरक्षित हैं। इस प्रकार, only() केवल अंतिम क्षेत्रों में परिणाम के लिए क्रमिक कॉल पर विचार किया जा रहा है:

# This will defer all fields except the headline.
Entry.objects.only("body", "rating").only("headline")

के बाद से defer() कार्य करता है संवर्द्धित (आस्थगित सूची फ़ील्ड जोड़ने), तो आप के लिए कॉल को जोड़ सकते हैं only() और defer() और चीजों को तार्किक रूप से व्यवहार करेंगे:

# Final result is that everything except "headline" is deferred.
Entry.objects.only("headline", "body").defer("body")

# Final result loads headline and body immediately (only() replaces any
# existing set of fields).
Entry.objects.defer("body").only("headline", "body")

defer() दस्तावेज़ के लिए नोट में सभी चेतावनियाँ भी लागू होती हैं only() । इसे सावधानी से और अपने अन्य विकल्पों को समाप्त करने के बाद ही उपयोग करें।

उपयोग किए गए only() फ़ील्ड का उपयोग करना और छोड़ना select_related() भी एक त्रुटि है।

ध्यान दें

save() स्थगित क्षेत्रों के साथ उदाहरणों के लिए कॉल करते समय, केवल लोड किए गए फ़ील्ड सहेजे जाएंगे। save() अधिक जानकारी के लिए देखें।

using()

using(alias)

यह विधि यह नियंत्रित करने के लिए है कि QuerySet यदि आप एक से अधिक डेटाबेस का उपयोग कर रहे हैं तो किस डेटाबेस का मूल्यांकन किया जाएगा। इस पद्धति का एकमात्र तर्क डेटाबेस का उपनाम है, जैसा कि परिभाषित किया गया है DATABASES

उदाहरण के लिए:

# queries the database with the 'default' alias.
>>> Entry.objects.all()

# queries the database with the 'backup' alias
>>> Entry.objects.using('backup')

select_for_update()

select_for_update(nowait=False, skip_locked=False, of=())

SELECT ... FOR UPDATE समर्थित डेटाबेस पर SQL स्टेटमेंट जेनरेट करते हुए क्वेरी के अंत तक पंक्तियों को लॉक करेगा, जो लेन-देन के अंत तक होता है ।

उदाहरण के लिए:

entries = Entry.objects.select_for_update().filter(author=request.user)

सभी मिलान वाली प्रविष्टियों को लेनदेन ब्लॉक के अंत तक लॉक किया जाएगा, जिसका अर्थ है कि अन्य लेनदेन को उन पर ताले बदलने या प्राप्त करने से रोका जाएगा।

आमतौर पर, यदि कोई अन्य लेनदेन पहले से ही चयनित पंक्तियों में से एक पर ताला लगा चुका है, तो ताला बंद होने तक क्वेरी अवरुद्ध हो जाएगी। यदि यह वह व्यवहार नहीं है जिसे आप चाहते हैं, तो कॉल करें select_for_update(nowait=True) । यह कॉल को गैर-अवरुद्ध कर देगा। यदि कोई परस्पर विरोधी लॉक पहले से ही किसी अन्य लेन-देन द्वारा अधिग्रहित किया जाता है, DatabaseError तो क्वेरी के मूल्यांकन के समय उठाया जाएगा। आप select_for_update(skip_locked=True) इसके बजाय का उपयोग करके बंद पंक्तियों को भी अनदेखा कर सकते हैं । nowait और skip_locked परस्पर अनन्य हैं और कॉल करने के लिए प्रयास करता है select_for_update() दोनों विकल्प सक्षम एक का परिणाम देगा के साथ ValueError

डिफ़ॉल्ट रूप से, select_for_update() क्वेरी द्वारा चयनित सभी पंक्तियों को लॉक कर देता है। उदाहरण के लिए, निर्दिष्ट ऑब्जेक्ट की select_related() पंक्तियों को क्वेरीसेट के मॉडल की पंक्तियों के अलावा लॉक किया गया है। यदि यह वांछित नहीं है, तो संबंधित select_for_update(of=(...)) फ़ील्ड निर्दिष्ट करें जिसे आप उसी फ़ील्ड सिंटैक्स का उपयोग करके लॉक करना चाहते हैं select_related() । मान 'self' का उपयोग क्वेरी के मॉडल को संदर्भित करने के लिए करें।

आप select_for_update() अशक्त संबंधों पर उपयोग नहीं कर सकते हैं :

>>> Person.objects.select_related('hometown').select_for_update()
Traceback (most recent call last):
...
django.db.utils.NotSupportedError: FOR UPDATE cannot be applied to the nullable side of an outer join

उस प्रतिबंध से बचने के लिए, यदि आप उनके बारे में परवाह नहीं करते हैं, तो आप अशक्त वस्तुओं को बाहर कर सकते हैं:

>>> Person.objects.select_related('hometown').select_for_update().exclude(hometown=None)
<QuerySet [<Person: ...)>, ...]>

वर्तमान में, postgresql , oracle , और mysql डेटाबेस बैकेंड समर्थन select_for_update() । हालांकि, MySQL का समर्थन नहीं करता nowait , skip_locked है, और of तर्क।

पासिंग nowait=True , skip_locked=True या of करने के लिए select_for_update() डेटाबेस बैकेंड कि इस तरह के MySQL के रूप में इन विकल्पों, का समर्थन नहीं करते, एक को जन्म देती है NotSupportedError । यह कोड को अप्रत्याशित रूप से अवरुद्ध होने से रोकता है।

select_for_update() बैकएंड पर ऑटोकॉमिट मोड के साथ एक क्वेरीसेट का मूल्यांकन करना जो SELECT ... FOR UPDATE एक TransactionManagementError त्रुटि है क्योंकि पंक्तियाँ उस स्थिति में लॉक नहीं होती हैं। यदि अनुमति दी जाती है, तो इससे डेटा भ्रष्टाचार में आसानी होगी और कॉल कोड के कारण आसानी से हो सकता है जो एक के बाहर लेनदेन में चलाने की अपेक्षा करता है।

select_for_update() बैकएंड पर उपयोग करना जो समर्थन नहीं करता SELECT ... FOR UPDATE (जैसे कि SQLite) का कोई प्रभाव नहीं होगा। SELECT ... FOR UPDATE क्वेरी में नहीं जोड़ा जाएगा, और यदि select_for_update() ऑटोोकॉमिट मोड में उपयोग किया जाता है तो एक त्रुटि नहीं उठाई जाती है।

चेतावनी

हालांकि select_for_update() आम तौर पर, autocommit मोड में विफल रहता है के बाद से TestCase स्वचालित रूप से, एक सौदे में प्रत्येक परीक्षा लपेटता बुला select_for_update() एक में TestCase भी एक के बाहर atomic() ब्लॉक होगा (शायद अप्रत्याशित रूप से) एक को ऊपर उठाने के बिना पारित TransactionManagementError । ठीक से परीक्षण करने के लिए select_for_update() आपको उपयोग करना चाहिए TransactionTestCase

कुछ अभिव्यक्तियों का समर्थन नहीं किया जा सकता है

PostgreSQL अभिव्यक्ति के select_for_update() साथ समर्थन नहीं करता है Window

Django 2.0 में बदला:

of तर्क जोड़ दिया गया।

raw()

raw(raw_query, params=None, translations=None)

एक कच्ची एसक्यूएल क्वेरी लेता है, इसे निष्पादित करता है, और एक django.db.models.query.RawQuerySet उदाहरण देता है । इस RawQuerySet उदाहरण को QuerySet ऑब्जेक्ट इंस्टेंसेस प्रदान करने के लिए सामान्य की तरह पुनरावृत्त किया जा सकता है ।

देखें प्रदर्शन कच्चे एसक्यूएल प्रश्नों और जानकारी के लिए।

चेतावनी

raw() हमेशा एक नई क्वेरी चलाता है और पिछले फ़िल्टरिंग के लिए खाता नहीं है। जैसे, इसे आम तौर पर Manager एक ताजा QuerySet उदाहरण से या से बुलाया जाना चाहिए ।

ऑपरेटरों कि वापसी नई QuerySet रों

संयुक्त क्वेरीज़ को उसी मॉडल का उपयोग करना चाहिए।

और ( & )

QuerySet SQL AND ऑपरेटर का उपयोग कर दो एस को जोड़ती है ।

निम्नलिखित समतुल्य हैं:

Model.objects.filter(x=1) & Model.objects.filter(y=2)
Model.objects.filter(x=1, y=2)
from django.db.models import Q
Model.objects.filter(Q(x=1) & Q(y=2))

SQL समकक्ष:

SELECT ... WHERE x=1 AND y=2

या ( | )

QuerySet SQL OR ऑपरेटर का उपयोग कर दो एस को जोड़ती है ।

निम्नलिखित समतुल्य हैं:

Model.objects.filter(x=1) | Model.objects.filter(y=2)
from django.db.models import Q
Model.objects.filter(Q(x=1) | Q(y=2))

SQL समकक्ष:

SELECT ... WHERE x=1 OR y=2

ऐसे तरीके जो QuerySet एस वापस नहीं करते हैं

निम्नलिखित QuerySet विधियों का मूल्यांकन करते हैं QuerySet और एक के अलावा कुछ और वापस करते हैं QuerySet

ये विधियाँ कैश का उपयोग नहीं करती हैं ( कैशिंग और क्वेरीस देखें )। बल्कि, वे डेटाबेस को हर बार जब वे बुलाए जाते हैं, तो क्वेरी करते हैं।

get()

get(**kwargs)

दिए गए लुकअप पैरामीटर्स से मेल खाती हुई वस्तु, जो फील्ड लुकअप में वर्णित प्रारूप में होनी चाहिए ।

get() MultipleObjectsReturned यदि एक से अधिक वस्तु मिली तो उठाता है। MultipleObjectsReturned अपवाद मॉडल वर्ग की एक विशेषता है।

get() DoesNotExist यदि कोई ऑब्जेक्ट दिए गए मापदंडों के लिए नहीं मिला था तो एक अपवाद उठाता है । यह अपवाद मॉडल वर्ग का एक गुण है। उदाहरण:

Entry.objects.get(id='foo') # raises Entry.DoesNotExist

DoesNotExist अपवाद से विरासत django.core.exceptions.ObjectDoesNotExist है, तो आप एक से अधिक लक्षित कर सकते हैं DoesNotExist अपवाद नहीं। उदाहरण:

from django.core.exceptions import ObjectDoesNotExist
try:
    e = Entry.objects.get(id=3)
    b = Blog.objects.get(id=1)
except ObjectDoesNotExist:
    print("Either the entry or blog doesn't exist.")

यदि आप किसी एक पंक्ति को वापस करने के लिए किसी क्वेरी की अपेक्षा करते हैं, तो आप get() उस पंक्ति के ऑब्जेक्ट को वापस करने के लिए बिना किसी तर्क के उपयोग कर सकते हैं :

entry = Entry.objects.filter(...).exclude(...).get()

create()

create(**kwargs)

ऑब्जेक्ट बनाने और इसे एक चरण में सहेजने के लिए एक सुविधा विधि। इस प्रकार:

p = Person.objects.create(first_name="Bruce", last_name="Springsteen")

तथा:

p = Person(first_name="Bruce", last_name="Springsteen")
p.save(force_insert=True)

समतुल्य हैं।

force_insert पैरामीटर कहीं और प्रलेखित है, लेकिन सभी इसका मतलब है कि एक नई वस्तु हमेशा बनाया जाएगा है। आम तौर पर आपको इस बारे में चिंता करने की आवश्यकता नहीं होगी। हालाँकि, यदि आपके मॉडल में एक मैन्युअल प्राथमिक कुंजी मान है जिसे आपने सेट किया है और यदि वह मान डेटाबेस में पहले से मौजूद है, तो प्राथमिक कुंजी के create() साथ कॉल विफल IntegrityError होने की संभावना अद्वितीय होगी। यदि आप मैन्युअल प्राथमिक कुंजियों का उपयोग कर रहे हैं, तो अपवाद को संभालने के लिए तैयार रहें।

get_or_create()

get_or_create(defaults=None, **kwargs)

दिए गए किसी ऑब्जेक्ट को देखने के लिए एक सुविधा विधि kwargs (यदि आपका मॉडल सभी क्षेत्रों के लिए डिफ़ॉल्ट है) खाली हो सकता है, तो यदि आवश्यक हो।

का एक टपल लौटाता है (object, created) , जहां object पुनर्प्राप्त या बनाई गई वस्तु है और created एक बूलियन निर्दिष्ट करता है कि क्या एक नई वस्तु बनाई गई थी।

इसका मतलब बॉयलरप्लेटिश कोड के शॉर्टकट के रूप में है। उदाहरण के लिए:

try:
    obj = Person.objects.get(first_name='John', last_name='Lennon')
except Person.DoesNotExist:
    obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
    obj.save()

जैसा कि एक मॉडल में फ़ील्ड्स की संख्या बढ़ती जाती है, यह पैटर्न काफी हद तक अस्पष्ट हो जाता है। उपरोक्त उदाहरण को इस get_or_create() तरह से उपयोग करके फिर से लिखा जा सकता है:

obj, created = Person.objects.get_or_create(
    first_name='John',
    last_name='Lennon',
    defaults={'birthday': date(1940, 10, 9)},
)

किसी भी कीवर्ड तर्कों को पारित कर दिया get_or_create() - को छोड़कर नामक एक वैकल्पिक एक defaults - एक में इस्तेमाल किया जाएगा get() कॉल। यदि कोई वस्तु पाई जाती है, तो get_or_create() उस वस्तु का एक टपल लौटाता है और False

आप चेनिंग द्वारा प्राप्त वस्तु के लिए अधिक जटिल परिस्थितियों निर्दिष्ट कर सकते हैं get_or_create() के साथ filter() और का उपयोग कर Q objects । उदाहरण के लिए, रॉबर्ट या बॉब मार्ले को पुनःप्राप्त करने के लिए या तो मौजूद है, और बाद में बनाएं अन्यथा:

from django.db.models import Q

obj, created = Person.objects.filter(
    Q(first_name='Bob') | Q(first_name='Robert'),
).get_or_create(last_name='Marley', defaults={'first_name': 'Bob'})

यदि कई ऑब्जेक्ट मिलते हैं, तो get_or_create() उठाता है MultipleObjectsReturned । यदि कोई वस्तु नहीं मिली है, get_or_create() तो एक नई वस्तु को टटोलेगा और बचाएगा, नई वस्तु का एक टपल लौटाएगा और True । नई वस्तु को इस एल्गोरिदम के अनुसार बनाया जाएगा:

params = {k: v for k, v in kwargs.items() if '__' not in k}
params.update({k: v() if callable(v) else v for k, v in defaults.items()})
obj = self.model(**params)
obj.save()

अंग्रेजी में, इसका मतलब है कि किसी भी गैर- 'defaults' कीवर्ड तर्क से शुरू करें जिसमें एक डबल अंडरस्कोर नहीं है (जो एक गैर-सटीक लुकअप को इंगित करेगा)। फिर defaults , यदि आवश्यक हो तो किसी भी कुंजी को ओवरराइड करने की सामग्री जोड़ें , और मॉडल वर्ग के लिए कीवर्ड तर्क के रूप में परिणाम का उपयोग करें। यदि कोई कॉलबेल हैं defaults , तो उनका मूल्यांकन करें। जैसा कि ऊपर संकेत दिया गया है, यह उपयोग किए जाने वाले एल्गोरिदम का एक सरलीकरण है, लेकिन इसमें सभी प्रासंगिक विवरण शामिल हैं। आंतरिक कार्यान्वयन में इसकी तुलना में कुछ अधिक त्रुटि-जाँच होती है और कुछ अतिरिक्त धार-स्थितियों को संभालता है; यदि आप रुचि रखते हैं, तो कोड पढ़ें।

यदि आपके पास कोई फ़ील्ड है, तो defaults इसे सटीक लुकअप के रूप में उपयोग करना चाहते हैं get_or_create() , बस उपयोग करें 'defaults__exact' , जैसे:

Foo.objects.get_or_create(defaults__exact='bar', defaults={'defaults': 'baz'})

get_or_create() विधि के समान त्रुटि व्यवहार है create() जब आप मैन्युअल रूप से निर्दिष्ट प्राथमिक कुंजी का उपयोग कर रहे हैं। यदि किसी ऑब्जेक्ट को बनाने की आवश्यकता है और कुंजी पहले से ही डेटाबेस में मौजूद है, तो एक IntegrityError उठाया जाएगा।

यह विधि अणुव्रत सही उपयोग, सही डेटाबेस विन्यास और अंतर्निहित डेटाबेस का सही व्यवहार है। हालाँकि, यदि कॉल (देखें या ) kwargs में उपयोग के लिए डेटाबेस स्तर पर विशिष्टता को लागू नहीं किया जाता है , तो यह विधि एक दौड़-स्थिति के लिए प्रवण होती है जिसके परिणामस्वरूप एक ही पैरामीटर के साथ कई पंक्तियों में परिणाम हो सकते हैं। get_or_create unique unique_together

यदि आप MySQL का उपयोग कर रहे हैं, READ COMMITTED तो REPEATABLE READ (डिफ़ॉल्ट) के बजाय आइसोलेशन स्तर का उपयोग करना सुनिश्चित करें , अन्यथा आप ऐसे मामलों को देख सकते हैं जहां get_or_create कोई समस्या उत्पन्न होगी, IntegrityError लेकिन ऑब्जेक्ट बाद के get() कॉल में दिखाई नहीं देगा ।

अंत में, get_or_create() Django के विचारों का उपयोग करने पर एक शब्द । कृपया इसे केवल POST अनुरोधों में उपयोग करना सुनिश्चित करें जब तक कि आपके पास कोई अच्छा कारण न हो। GET अनुरोधों का डेटा पर कोई प्रभाव नहीं होना चाहिए। इसके बजाय, POST जब भी किसी पृष्ठ के अनुरोध का आपके डेटा पर दुष्प्रभाव पड़ता है, तो उसका उपयोग करें अधिक के लिए, HTTP युक्ति में सुरक्षित तरीके देखें ।

चेतावनी

आप विशेषताओं और रिवर्स संबंधों के get_or_create() माध्यम से उपयोग कर सकते हैं ManyToManyField । उस स्थिति में आप उस संबंध के संदर्भ में प्रश्नों को प्रतिबंधित करेंगे। यदि आप इसे लगातार उपयोग नहीं करते हैं, तो आप कुछ अखंडता समस्याओं को जन्म दे सकते हैं।

निम्नलिखित मॉडल होने के नाते:

class Chapter(models.Model):
    title = models.CharField(max_length=255, unique=True)

class Book(models.Model):
    title = models.CharField(max_length=256)
    chapters = models.ManyToManyField(Chapter)

आप get_or_create() पुस्तक के अध्याय क्षेत्र के माध्यम से उपयोग कर सकते हैं , लेकिन यह केवल उस पुस्तक के संदर्भ में ही प्राप्त होता है:

>>> book = Book.objects.create(title="Ulysses")
>>> book.chapters.get_or_create(title="Telemachus")
(<Chapter: Telemachus>, True)
>>> book.chapters.get_or_create(title="Telemachus")
(<Chapter: Telemachus>, False)
>>> Chapter.objects.create(title="Chapter 1")
<Chapter: Chapter 1>
>>> book.chapters.get_or_create(title="Chapter 1")
# Raises IntegrityError

यह इसलिए हो रहा है क्योंकि यह "Ulysses" पुस्तक के माध्यम से "अध्याय 1" प्राप्त करने या बनाने की कोशिश कर रहा है, लेकिन यह उनमें से कोई भी नहीं कर सकता: रिश्ता उस अध्याय को प्राप्त नहीं कर सकता क्योंकि यह उस पुस्तक से संबंधित नहीं है, लेकिन यह या तो इसे नहीं बना सकता क्योंकि title फ़ील्ड अद्वितीय होना चाहिए।

update_or_create()

update_or_create(defaults=None, **kwargs)

दिए गए ऑब्जेक्ट के साथ अद्यतन करने के लिए एक सुविधा विधि kwargs , यदि आवश्यक हो तो एक नया निर्माण। defaults (क्षेत्र, मूल्य) वस्तु को अद्यतन करने के लिए प्रयोग किया जाता जोड़े का एक शब्दकोश है। में मूल्यों defaults callables जा सकता है।

का एक टपल लौटाता है (object, created) , जहां object बनाई गई या अद्यतन की गई वस्तु है और created एक बूलियन निर्दिष्ट करता है कि क्या एक नई वस्तु बनाई गई थी।

update_or_create विधि के आधार पर दिए गए डेटाबेस से एक वस्तु लाने की कोशिश करता है kwargs । यदि कोई मिलान पाया जाता है, तो यह defaults शब्दकोश में उत्तीर्ण क्षेत्रों को अद्यतन करता है ।

इसका मतलब बॉयलरप्लेटिश कोड के शॉर्टकट के रूप में है। उदाहरण के लिए:

defaults = {'first_name': 'Bob'}
try:
    obj = Person.objects.get(first_name='John', last_name='Lennon')
    for key, value in defaults.items():
        setattr(obj, key, value)
    obj.save()
except Person.DoesNotExist:
    new_values = {'first_name': 'John', 'last_name': 'Lennon'}
    new_values.update(defaults)
    obj = Person(**new_values)
    obj.save()

जैसा कि एक मॉडल में फ़ील्ड्स की संख्या बढ़ती जाती है, यह पैटर्न काफी हद तक अस्पष्ट हो जाता है। उपरोक्त उदाहरण को इस update_or_create() तरह से उपयोग करके फिर से लिखा जा सकता है:

obj, created = Person.objects.update_or_create(
    first_name='John', last_name='Lennon',
    defaults={'first_name': 'Bob'},
)

विस्तृत विवरण के लिए कैसे नाम पारित kwargs किए गए हल देखें get_or_create()

जैसा कि ऊपर वर्णित है get_or_create() , यह विधि एक दौड़-स्थिति के लिए प्रवण है जिसके परिणामस्वरूप कई पंक्तियों को एक साथ डाला जा सकता है यदि डेटाबेस स्तर पर विशिष्टता लागू नहीं की जाती है।

जैसा get_or_create() और create() , आप मैन्युअल निर्दिष्ट प्राथमिक कुंजी का उपयोग कर रहे हैं और एक वस्तु बनाने की आवश्यकता है, लेकिन कुंजी पहले से डेटाबेस में मौजूद रहने पर, एक IntegrityError उठाया जाता है।

bulk_create()

bulk_create(objs, batch_size=None)

यह विधि डेटाबेस में एक कुशल तरीके से वस्तुओं की प्रदान की गई सूची सम्मिलित करती है (आम तौर पर केवल 1 क्वेरी, चाहे कितनी भी वस्तुएं हों):

>>> Entry.objects.bulk_create([
...     Entry(headline='This is a test'),
...     Entry(headline='This is only a test'),
... ])

हालांकि इसमें कई संख्याएँ हैं:

  • मॉडल की save() विधि को नहीं बुलाया जाएगा, pre_save और post_save सिग्नल नहीं भेजे जाएंगे।
  • यह मल्टी-टेबल इनहेरिटेंस परिदृश्य में बाल मॉडल के साथ काम नहीं करता है।
  • यदि मॉडल की प्राथमिक कुंजी है, तो AutoField यह प्राथमिक कुंजी विशेषता को पुनर्प्राप्त और सेट नहीं करता है, जैसा कि save() करता है, जब तक कि डेटाबेस बैकेंड इसका समर्थन नहीं करता है (वर्तमान में PostgreSQL)।
  • यह कई-कई रिश्तों के साथ काम नहीं करता है।
  • यह objs एक सूची में आता है, जो पूरी तरह से मूल्यांकन करता है objs कि क्या यह एक जनरेटर है। कलाकार सभी वस्तुओं का निरीक्षण करने की अनुमति देता है ताकि किसी भी ऑब्जेक्ट को मैन्युअल रूप से सेट की गई प्राथमिक कुंजी के साथ डाला जा सके। यदि आप एक ही समय में पूरे जनरेटर का मूल्यांकन किए बिना बैचों में ऑब्जेक्ट सम्मिलित करना चाहते हैं, तो आप इस तकनीक का उपयोग तब तक कर सकते हैं जब तक कि ऑब्जेक्ट्स में मैन्युअल रूप से सेट की गई प्राथमिक कुंजी न हों:

    from itertools import islice
    
    batch_size = 100
    objs = (Entry(headline='Test %s' % i) for i in range(1000))
    while True:
        batch = list(islice(objs, batch_size))
        if not batch:
            break
        Entry.objects.bulk_create(batch, batch_size)
    

batch_size पैरामीटर को नियंत्रित करता है कि कितने वस्तुओं किसी एक क्वेरी में बनाया जाता है। डिफ़ॉल्ट को एक बैच में सभी ऑब्जेक्ट्स बनाने के लिए, SQLite को छोड़कर, जहां डिफ़ॉल्ट ऐसा है कि प्रति क्वेरी में अधिकतम 999 चर उपयोग किए जाते हैं।

count()

count()

डेटाबेस में वस्तुओं की संख्या का प्रतिनिधित्व करते हुए एक पूर्णांक लौटाता है जिससे मिलान होता है QuerySet

उदाहरण:

# Returns the total number of entries in the database.
Entry.objects.count()

# Returns the number of entries whose headline contains 'Lennon'
Entry.objects.filter(headline__contains='Lennon').count()

एक count() कॉल SELECT COUNT(*) पर्दे के पीछे करता है , इसलिए आपको हमेशा count() रिकॉर्ड के सभी को पाइथन ऑब्जेक्ट्स में लोड करने और len() परिणाम पर कॉल करने के बजाय उपयोग करना चाहिए (जब तक कि आपको ऑब्जेक्ट को मेमोरी में लोड करने की आवश्यकता नहीं होती है, जिसमें मामला len() तेज होगा)।

ध्यान दें कि यदि आप आइटम की संख्या चाहते QuerySet हैं (और इसमें से मॉडल उदाहरण भी प्राप्त कर रहे हैं (उदाहरण के लिए, इस पर पुनरावृत्ति करके), तो यह संभवतः उपयोग करने के लिए अधिक कुशल है len(queryset) जो अतिरिक्त डेटाबेस क्वेरी का कारण नहीं count() होगा।

in_bulk()

in_bulk(id_list=None, field_name='pk')

फ़ील्ड मानों की एक सूची ( id_list ) और field_name उन मानों के लिए लेता है , और दिए गए फ़ील्ड मान के साथ ऑब्जेक्ट के एक उदाहरण के लिए प्रत्येक मान मैपिंग शब्दकोश देता है। यदि id_list प्रदान नहीं किया गया है, तो क्वेरीसेट की सभी वस्तुएँ वापस कर दी जाती हैं। field_name एक अद्वितीय फ़ील्ड होना चाहिए, और यह प्राथमिक कुंजी को डिफॉल्ट करता है।

उदाहरण:

>>> Blog.objects.in_bulk([1])
{1: <Blog: Beatles Blog>}
>>> Blog.objects.in_bulk([1, 2])
{1: <Blog: Beatles Blog>, 2: <Blog: Cheddar Talk>}
>>> Blog.objects.in_bulk([])
{}
>>> Blog.objects.in_bulk()
{1: <Blog: Beatles Blog>, 2: <Blog: Cheddar Talk>, 3: <Blog: Django Weblog>}
>>> Blog.objects.in_bulk(['beatles_blog'], field_name='slug')
{'beatles_blog': <Blog: Beatles Blog>}

यदि आप in_bulk() एक खाली सूची पास करते हैं, तो आपको एक खाली शब्दकोश मिलेगा।

Django 2.0 में बदला:

field_name पैरामीटर जोड़ दिया गया।

iterator()

iterator(chunk_size=2000)

QuerySet (क्वेरी को निष्पादित करके) का मूल्यांकन करता है और परिणामों पर एक पुनरावृत्ति ( पीईपी 234 देखें ) देता है। एक QuerySet आम तौर पर उसके परिणामों आंतरिक रूप से कैश ताकि बार-बार मूल्यांकन अतिरिक्त प्रश्नों में परिणाम नहीं है। इसके विपरीत, स्तर iterator() पर कोई कैशिंग किए बिना, सीधे परिणाम पढ़ेंगे QuerySet (आंतरिक रूप से, डिफ़ॉल्ट पुनरावृत्तिकर्ता कॉल iterator() और रिटर्न वैल्यू को कैश करता है)। QuerySet जिसके लिए बड़ी संख्या में ऐसी वस्तुएँ वापस आती हैं जिन्हें आपको केवल एक बार एक्सेस करने की आवश्यकता होती है, इसके परिणामस्वरूप बेहतर प्रदर्शन और स्मृति में महत्वपूर्ण कमी हो सकती है।

ध्यान दें कि का उपयोग कर iterator() एक पर QuerySet जो पहले से ही फिर से मूल्यांकन करने के लिए यह बाध्य करेगा का मूल्यांकन किया गया है, क्वेरी दोहरा।

इसके अलावा, iterator() पिछली prefetch_related() कॉल के कारणों का उपयोग अनदेखा किया जाना चाहिए क्योंकि ये दोनों अनुकूलन एक साथ समझ में नहीं आते हैं।

डेटाबेस बैकएंड के आधार पर, क्वेरी परिणाम या तो एक ही बार में लोड किए जाएंगे या सर्वर-साइड कर्सर का उपयोग करके डेटाबेस से स्ट्रीम किया जाएगा।

सर्वर-साइड कर्सर के साथ

Oracle और PostgreSQL सर्वर-साइड कर्सर को मेमोरी में सेट किए गए पूरे परिणाम को लोड किए बिना डेटाबेस से परिणाम स्ट्रीम करने के लिए उपयोग करते हैं।

Oracle डेटाबेस ड्राइवर हमेशा सर्वर-साइड कर्सर का उपयोग करता है।

सर्वर-साइड कर्सर के साथ, chunk_size पैरामीटर डेटाबेस ड्राइवर स्तर पर कैश करने के लिए परिणामों की संख्या निर्दिष्ट करता है। बड़ी मात्रा में चॉक्सेस प्राप्त करने से डेटाबेस ड्राइवर और डेटाबेस के बीच मेमोरी की कीमत पर राउंड ट्रिप की संख्या कम हो जाती है।

PostgreSQL पर, सर्वर-साइड कर्सर केवल DISABLE_SERVER_SIDE_CURSORS सेटिंग के समय उपयोग किया जाएगा False लेन- देन पूलिंग मोड में कॉन्फ़िगर किए गए कनेक्शन पूलर का उपयोग कर रहे हैं, तो लेन-देन पूलिंग और सर्वर-साइड कर्सर पढ़ें । जब सर्वर-साइड कर्सर अक्षम होते हैं, तो व्यवहार डेटाबेस के समान होता है जो सर्वर-साइड कर्सर का समर्थन नहीं करता है।

सर्वर-साइड कर्सर के बिना

MySQL और SQLite स्ट्रीमिंग परिणामों का समर्थन नहीं करते हैं, इसलिए पायथन डेटाबेस ड्राइवर पूरे परिणाम को मेमोरी में सेट करते हैं। परिणाम सेट तब PEP 249 fetchmany() में परिभाषित विधि का उपयोग करके डेटाबेस एडेप्टर द्वारा पायथन पंक्ति वस्तुओं में बदल दिया जाता है ।

chunk_size पैरामीटर Django डेटाबेस ड्राइवर से पुन: प्राप्त करता बैचों के आकार को नियंत्रित। बड़े बैच स्मृति खपत में मामूली वृद्धि की कीमत पर डेटाबेस ड्राइवर के साथ संचार के ओवरहेड को कम करते हैं।

chunk_size 2000 का डिफ़ॉल्ट मान , psycopg मेलिंग सूची की गणना से आता है :

पाठ्य और संख्यात्मक डेटा के मिश्रण के साथ 10-20 स्तंभों की पंक्तियों को मानते हुए, 2000 100KB से कम डेटा प्राप्त करने जा रहा है, जो स्थानांतरित की गई पंक्तियों की संख्या और लूप के जल्दी बाहर होने पर हटाए गए डेटा के बीच एक अच्छा समझौता है।
Django 2.0 में बदला:

chunk_size पैरामीटर जोड़ दिया गया।

latest()

latest(*fields)

दी गई फ़ील्ड के आधार पर तालिका में नवीनतम वस्तु लौटाता है।

यह उदाहरण क्षेत्र के Entry अनुसार तालिका में नवीनतम रिटर्न देता है pub_date :

Entry.objects.latest('pub_date')

आप कई क्षेत्रों के आधार पर नवीनतम भी चुन सकते हैं। उदाहरण के लिए, दो प्रविष्टियों के समान होने Entry पर जल्द से जल्द चयन करने के लिए : expire_date pub_date

Entry.objects.latest('pub_date', '-expire_date')

अवरोही क्रम में '-expire_date' क्रमबद्ध करने के लिए नकारात्मक संकेत । चूंकि अंतिम परिणाम मिलता है, जल्द से जल्द चुना जाता है। expire_date latest() Entry expire_date

यदि आपके मॉडल का Meta निर्दिष्ट करता है get_latest_by , तो आप earliest() या तो किसी भी तर्क को छोड़ सकते हैं latest() । निर्दिष्ट फ़ील्ड get_latest_by डिफ़ॉल्ट रूप से उपयोग किए जाएंगे।

यदि दिए गए मापदंडों के साथ कोई वस्तु नहीं है get() , तो जैसे earliest() और latest() बढ़ाएं DoesNotExist

ध्यान दें कि earliest() और latest() सुविधा और पठनीयता के लिए विशुद्ध रूप से मौजूद हैं।

Django 2.0 में बदला:

कई तर्कों के लिए समर्थन जोड़ा गया था।

earliest() और latest() अशक्त तिथियों के साथ उदाहरण लौटा सकते हैं।

चूंकि ऑर्डर डेटाबेस को सौंपा गया है, इसलिए यदि आप अलग-अलग डेटाबेस का उपयोग करते हैं, तो शून्य मानों की अनुमति देने वाले फ़ील्ड के परिणाम अलग-अलग ऑर्डर किए जा सकते हैं। उदाहरण के लिए, PostgreSQL और MySQL अशक्त मूल्यों को छाँटते हैं जैसे कि वे गैर-शून्य मानों से अधिक हैं, जबकि SQLite इसके विपरीत करता है।

आप शून्य मानों को फ़िल्टर करना चाह सकते हैं:

Entry.objects.filter(pub_date__isnull=False).latest('pub_date')

earliest()

earliest(*fields)

latest() दिशा बदलने के अलावा अन्यथा काम करता है।

first()

first()

क्वेरी द्वारा मिलान की गई पहली वस्तु लौटाता है, या None यदि कोई मेल खाने वाली वस्तु नहीं है। यदि QuerySet कोई ऑर्डरिंग परिभाषित नहीं है, तो प्राथमिक कुंजी द्वारा क्वेरीसेट स्वचालित रूप से ऑर्डर किया जाता है। यह डिफ़ॉल्ट परिणाम या order_by () के साथ इंटरैक्शन में वर्णित एकत्रीकरण परिणामों को प्रभावित कर सकता है ।

उदाहरण:

p = Article.objects.order_by('title', 'pub_date').first()

ध्यान दें कि first() एक सुविधा विधि है, निम्नलिखित कोड नमूना उपरोक्त उदाहरण के बराबर है:

try:
    p = Article.objects.order_by('title', 'pub_date')[0]
except IndexError:
    p = None

last()

last()

काम करता है first() , लेकिन क्वेरी में अंतिम ऑब्जेक्ट देता है।

aggregate()

aggregate(*args, **kwargs)

कुल मूल्यों (औसत, रकम आदि) का एक शब्दकोश देता है QuerySet । प्रत्येक तर्क aggregate() एक मान को निर्दिष्ट करता है जिसे वापस लौटाए जाने वाले शब्दकोश में शामिल किया जाएगा।

Django द्वारा प्रदान किए जाने वाले एकत्रीकरण कार्य नीचे दिए गए एकत्रीकरण कार्यों में वर्णित हैं। चूंकि एग्रीगेट भी क्वेरी एक्सप्रेशन हैं , आप कॉम्प्लेक्स एग्रीगेट्स बनाने के लिए अन्य एग्रीगेट या वैल्यू के साथ एग्रीगेट्स को जोड़ सकते हैं।

कीवर्ड तर्कों का उपयोग करके निर्दिष्ट एग्रीगेट्स कीवर्ड का उपयोग एनोटेशन के नाम के रूप में करेंगे। अनाम तर्कों में उनके लिए एक नाम होगा जो कुल कार्य और मॉडल क्षेत्र के नाम पर आधारित होगा जो एकत्र किया जा रहा है। जटिल समुच्चय अनाम तर्क का उपयोग नहीं कर सकते हैं और उन्हें उपनाम के रूप में एक कीवर्ड तर्क निर्दिष्ट करना होगा।

उदाहरण के लिए, जब आप ब्लॉग प्रविष्टियों के साथ काम कर रहे हैं, तो आप उन लेखकों की संख्या जानना चाह सकते हैं जिन्होंने ब्लॉग प्रविष्टियों में योगदान दिया है:

>>> from django.db.models import Count
>>> q = Blog.objects.aggregate(Count('entry'))
{'entry__count': 16}

कुल फ़ंक्शन को निर्दिष्ट करने के लिए एक कीवर्ड तर्क का उपयोग करके, आप एकत्र किए गए एकत्रीकरण मान के नाम को नियंत्रित कर सकते हैं:

>>> q = Blog.objects.aggregate(number_of_entries=Count('entry'))
{'number_of_entries': 16}

एकत्रीकरण की गहन चर्चा के लिए, एकत्रीकरण पर विषय मार्गदर्शिका देखें ।

exists()

exists()

रिटर्न True अगर QuerySet कोई भी परिणाम होते हैं, और False नहीं तो। यह क्वेरी को सबसे सरल और सबसे तेज़ तरीके से निष्पादित करने की कोशिश करता है, लेकिन यह सामान्य क्वेरी के समान लगभग एक ही क्वेरी को निष्पादित करता है QuerySet

exists() विशेष रूप से एक बड़े के संदर्भ में QuerySet किसी भी वस्तु के अस्तित्व में (और में दोनों ऑब्जेक्ट सदस्यता से संबंधित खोजों के लिए उपयोगी है । QuerySet QuerySet

यह पता लगाने का सबसे कुशल तरीका है कि क्या एक अद्वितीय क्षेत्र (जैसे primary_key ) वाला मॉडल एक का एक सदस्य QuerySet है:

entry = Entry.objects.get(pk=123)
if some_queryset.filter(pk=entry.pk).exists():
    print("Entry contained in queryset")

जो निम्नलिखित की तुलना में अधिक तेज़ होगा जिसे संपूर्ण क्वेरी के माध्यम से मूल्यांकन और पुनरावृति की आवश्यकता होती है:

if entry in some_queryset:
   print("Entry contained in QuerySet")

और यह जानने के लिए कि क्या किसी क्वेरी में कोई आइटम शामिल हैं:

if some_queryset.exists():
    print("There is at least one object in some_queryset")

जो इससे तेज होगा:

if some_queryset:
    print("There is at least one object in some_queryset")

... लेकिन एक बड़ी डिग्री से नहीं (इसलिए दक्षता लाभ के लिए एक बड़ी क्वेरी की जरूरत है)।

इसके अतिरिक्त, यदि some_queryset अभी तक मूल्यांकन नहीं किया गया है, लेकिन आप जानते हैं कि यह किसी बिंदु पर होगा, तो उपयोग some_queryset.exists() करने से अधिक समग्र कार्य होगा (अस्तित्व की जांच के लिए एक क्वेरी प्लस एक अतिरिक्त एक बाद में परिणाम प्राप्त करने के लिए) बस का उपयोग करके bool(some_queryset) , जो परिणामों को पुनः प्राप्त करता है और फिर जाँचता है कि क्या कोई लौटाया गया था।

update()

update(**kwargs)

निर्दिष्ट फ़ील्ड के लिए SQL अद्यतन क्वेरी करता है, और मिलान की गई पंक्तियों की संख्या लौटाता है (जो कुछ पंक्तियों की संख्या के बराबर नहीं हो सकती है यदि कुछ पंक्तियों में पहले से ही नया मान है)।

उदाहरण के लिए, 2010 में प्रकाशित सभी ब्लॉग प्रविष्टियों के लिए टिप्पणियाँ बंद करने के लिए, आप ऐसा कर सकते हैं:

>>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False)

(यह मानता है कि आपके Entry मॉडल में फ़ील्ड हैं pub_date और comments_on )

आप कई फ़ील्ड अपडेट कर सकते हैं - कितने पर कोई सीमा नहीं है। उदाहरण के लिए, यहां हम फ़ील्ड comments_on और headline फ़ील्ड अपडेट करते हैं:

>>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False, headline='This is old')

यह update() विधि तुरंत लागू की जाती है, और उस पर एकमात्र प्रतिबंध QuerySet अद्यतन किया जाता है, यह केवल मॉडल की मुख्य तालिका में कॉलम अपडेट कर सकता है, संबंधित मॉडल पर नहीं। आप ऐसा नहीं कर सकते, उदाहरण के लिए:

>>> Entry.objects.update(blog__name='foo') # Won't work!

संबंधित क्षेत्रों पर आधारित फ़िल्टरिंग अभी भी संभव है, हालांकि:

>>> Entry.objects.filter(blog__id=1).update(comments_on=True)

आप उस update() पर कॉल नहीं कर सकते हैं QuerySet जिसमें एक स्लाइस लिया गया है या अन्यथा अब फ़िल्टर नहीं किया जा सकता है।

update() विधि प्रभावित पंक्तियों की संख्या देता है:

>>> Entry.objects.filter(id=64).update(comments_on=True)
1

>>> Entry.objects.filter(slug='nonexistent-slug').update(comments_on=True)
0

>>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False)
132

यदि आप केवल रिकॉर्ड अपडेट कर रहे हैं और मॉडल ऑब्जेक्ट के साथ कुछ भी करने की आवश्यकता नहीं है, तो update() मेमोरी में मॉडल ऑब्जेक्ट को लोड करने के बजाय कॉल करने के लिए सबसे कुशल दृष्टिकोण है । उदाहरण के लिए, ऐसा करने के बजाय:

e = Entry.objects.get(id=10)
e.comments_on = False
e.save()

…यह करो:

Entry.objects.filter(id=10).update(comments_on=False)

का उपयोग करना update() भी एक दौड़ की स्थिति को रोकता है जिसमें वस्तु और कॉलिंग के बीच कम समय में आपके डेटाबेस में कुछ बदल सकता है save()

अंत में, महसूस करें कि update() SQL स्तर पर एक अद्यतन करता है और इस प्रकार, save() अपने मॉडल पर किसी भी तरीके को कॉल नहीं करता है , और न ही यह pre_save या post_save संकेतों (जो कॉल करने का एक परिणाम है save() ) का उत्सर्जन नहीं करता है । यदि आप एक मॉडल के लिए रिकॉर्ड का एक गुच्छा अद्यतन करना चाहते हैं जिसमें एक कस्टम save() विधि है, तो उन पर लूप करें और कॉल करें save() , जैसे:

for e in Entry.objects.filter(pub_date__year=2010):
    e.comments_on = False
    e.save()

delete()

delete()

में सभी पंक्तियों पर एक SQL डिलीट क्वेरी करता QuerySet है और हटाए गए ऑब्जेक्ट की संख्या और ऑब्जेक्ट प्रकार प्रति विलोपन की संख्या के साथ एक शब्दकोश देता है।

delete() तुरंत लागू किया जाता है। आप उस delete() पर कॉल नहीं कर सकते हैं QuerySet जिसमें एक स्लाइस लिया गया है या अन्यथा अब फ़िल्टर नहीं किया जा सकता है।

उदाहरण के लिए, किसी विशेष ब्लॉग की सभी प्रविष्टियों को हटाने के लिए:

>>> b = Blog.objects.get(pk=1)

# Delete all the entries belonging to this Blog.
>>> Entry.objects.filter(blog=b).delete()
(4, {'weblog.Entry': 2, 'weblog.Entry_authors': 2})

डिफ़ॉल्ट रूप से, Django ForeignKey एसक्यूएल बाधा का अनुकरण करता है ON DELETE CASCADE - दूसरे शब्दों में, विदेशी कुंजी के साथ किसी भी ऑब्जेक्ट को हटाए जाने वाले ऑब्जेक्ट को इंगित करने के साथ हटा दिया जाएगा। उदाहरण के लिए:

>>> blogs = Blog.objects.all()

# This will delete all Blogs and all of their Entry objects.
>>> blogs.delete()
(5, {'weblog.Blog': 1, 'weblog.Entry': 2, 'weblog.Entry_authors': 2})

यह कैस्केड व्यवहार on_delete तर्क के माध्यम से अनुकूलन योग्य है ForeignKey

delete() विधि एक थोक हटाना करता है और किसी भी फोन नहीं करता है delete() अपने मॉडल पर तरीकों। हालाँकि, यह सभी हटाए गए ऑब्जेक्ट्स (कैस्केड विलोपन सहित) के लिए pre_delete और post_delete संकेतों का उत्सर्जन करता है ।

Django को सिग्नल भेजने और कैस्केड को संभालने के लिए मेमोरी में ऑब्जेक्ट लाने की जरूरत है। हालांकि, अगर कोई कैस्केड और कोई सिग्नल नहीं हैं, तो Django एक तेज़-पथ ले सकता है और मेमोरी में लाए बिना ऑब्जेक्ट हटा सकता है। बड़े डिलीट के लिए यह काफी कम मेमोरी का उपयोग कर सकता है। निष्पादित प्रश्नों की मात्रा को कम भी किया जा सकता है।

फ़ॉरेनकाइज़ जो हटाने के लिए तेज़-पथ को रोकने के लिए सेट नहीं हैं। on_delete DO_NOTHING

ध्यान दें कि ऑब्जेक्ट विलोपन में उत्पन्न क्वेरीज़ परिवर्तन के अधीन कार्यान्वयन विवरण है।

as_manager()

classmethod as_manager()

वर्ग विधि जो 'की विधियों Manager की एक प्रति के साथ एक उदाहरण लौटाती है QuerySet । अधिक विवरण के लिए QuerySet विधियों के साथ एक प्रबंधक बनाना देखें ।

explain()

Django 2.1 में नया:
explain(format=None, **options)

एक QuerySet निष्पादन योजना की एक स्ट्रिंग लौटाता है , जो यह बताता है कि डेटाबेस क्वेरी का निष्पादन कैसे करेगा, जिसमें किसी भी इंडेक्स या जॉइन को शामिल किया जाएगा। इन विवरणों को जानने से आपको धीमी क्वेरी के प्रदर्शन में सुधार करने में मदद मिल सकती है।

उदाहरण के लिए, PostgreSQL का उपयोग करते समय:

>>> print(Blog.objects.filter(title='My Blog').explain())
Seq Scan on blog  (cost=0.00..35.50 rows=10 width=12)
  Filter: (title = 'My Blog'::bpchar)

डेटाबेस के बीच आउटपुट में काफी अंतर होता है।

explain() ओरेकल को छोड़कर सभी बिल्ट-इन डेटाबेस बैकएंड द्वारा समर्थित है क्योंकि एक कार्यान्वयन वहाँ सीधा नहीं है।

format पैरामीटर में परिवर्तन डेटाबेस के डिफ़ॉल्ट से उत्पादन प्रारूप, आम तौर पर पाठ आधारित। PostgreSQL का समर्थन करता है 'TEXT' , 'JSON' , 'YAML' , और 'XML' । MySQL का समर्थन करता है 'TEXT' (भी कहा जाता है 'TRADITIONAL' ) और 'JSON'

कुछ डेटाबेस झंडे को स्वीकार करते हैं जो क्वेरी के बारे में अधिक जानकारी वापस कर सकते हैं। इन झंडों को कीवर्ड तर्क के रूप में पास करें। उदाहरण के लिए, PostgreSQL का उपयोग करते समय:

>>> print(Blog.objects.filter(title='My Blog').explain(verbose=True))
Seq Scan on public.blog  (cost=0.00..35.50 rows=10 width=12) (actual time=0.004..0.004 rows=10 loops=1)
  Output: id, title
  Filter: (blog.title = 'My Blog'::bpchar)
Planning time: 0.064 ms
Execution time: 0.058 ms

कुछ डेटाबेस पर, झंडे के कारण क्वेरी निष्पादित हो सकती है जो आपके डेटाबेस पर प्रतिकूल प्रभाव डाल सकती है। उदाहरण के लिए, PostgreSQL के ANALYZE झंडे के परिणामस्वरूप डेटा में परिवर्तन हो सकते हैं यदि कोई ट्रिगर है या यदि कोई फ़ंक्शन कहा जाता है, तो SELECT क्वेरी के लिए भी ।

Field लुकअप

फ़ील्ड लुकअप आप SQL WHERE क्लॉज का मांस कैसे निर्दिष्ट करते हैं । वे QuerySet विधियों के कीवर्ड तर्क के रूप में निर्दिष्ट हैं filter() , exclude() और get()

एक परिचय के लिए, मॉडल और डेटाबेस क्वेरीज़ प्रलेखन देखें

Django के अंतर्निहित लुकअप नीचे सूचीबद्ध हैं। मॉडल फ़ील्ड के लिए कस्टम लुकअप लिखना भी संभव है ।

सुविधा के रूप में जब कोई लुकअप प्रकार प्रदान नहीं किया जाता है (जैसे Entry.objects.get(id=14) ) में लुकअप प्रकार माना जाता है exact

exact

सटीक मिलान। यदि तुलना के लिए प्रदान किया गया मान है None , तो इसे SQL के रूप में व्याख्या की जाएगी NULL ( isnull अधिक विवरण के लिए देखें)।

उदाहरण:

Entry.objects.get(id__exact=14)
Entry.objects.get(id__exact=None)

एसक्यूएल समकक्ष:

SELECT ... WHERE id = 14;
SELECT ... WHERE id IS NULL;

MySQL की तुलना

MySQL में, एक डेटाबेस टेबल की "कॉलेशन" सेटिंग यह निर्धारित करती है कि exact तुलना केस-संवेदी है या नहीं। यह एक डेटाबेस सेटिंग है, कि Django सेटिंग। केस-संवेदी तुलना का उपयोग करने के लिए अपने MySQL तालिकाओं को कॉन्फ़िगर करना संभव है, लेकिन कुछ ट्रेड-ऑफ शामिल हैं। इसके बारे में अधिक जानकारी के लिए, databases प्रलेखन में टकराव अनुभाग देखें । databases

iexact

केस-असंवेदनशील सटीक मिलान। यदि तुलना के लिए प्रदान किया गया मान है None , तो इसे SQL के रूप में व्याख्या की जाएगी NULL ( isnull अधिक विवरण के लिए देखें)।

उदाहरण:

Blog.objects.get(name__iexact='beatles blog')
Blog.objects.get(name__iexact=None)

एसक्यूएल समकक्ष:

SELECT ... WHERE name ILIKE 'beatles blog';
SELECT ... WHERE name IS NULL;

नोट पहली क्वेरी से मेल खाएगी 'Beatles Blog' , 'beatles blog' , 'BeAtLes BLoG' , आदि

SQLite उपयोगकर्ताओं

SQLite बैकएंड और गैर- ASCII तार का उपयोग करते समय, स्ट्रिंग तुलना के बारे में डेटाबेस नोट पर ध्यान दें । गैर-ASCII तार के लिए SQLite केस-असंवेदनशील मिलान नहीं करता है।

contains

केस-संवेदी नियंत्रण परीक्षण।

उदाहरण:

Entry.objects.get(headline__contains='Lennon')

SQL समकक्ष:

SELECT ... WHERE headline LIKE '%Lennon%';

ध्यान दें कि यह शीर्षक से मेल खाएगा 'Lennon honored today' लेकिन नहीं 'lennon honored today'

SQLite उपयोगकर्ताओं

SQLite केस-संवेदी LIKE बयानों का समर्थन नहीं करता है ; SQLite के लिए contains कार्य करता है icontains । देखें डेटाबेस टिप्पणी अधिक जानकारी के लिए।

icontains

केस-असंवेदनशील नियंत्रण परीक्षण।

उदाहरण:

Entry.objects.get(headline__icontains='Lennon')

SQL समकक्ष:

SELECT ... WHERE headline ILIKE '%Lennon%';

SQLite उपयोगकर्ताओं

SQLite बैकएंड और गैर- ASCII तार का उपयोग करते समय, स्ट्रिंग तुलना के बारे में डेटाबेस नोट पर ध्यान दें

in

दिए गए पुनरावृति में; अक्सर एक सूची, टपल, या क्वेरीसेट। यह एक सामान्य उपयोग का मामला नहीं है, लेकिन तार (पुनरावृत्त होने के नाते) स्वीकार किए जाते हैं।

उदाहरण:

Entry.objects.filter(id__in=[1, 3, 4])
Entry.objects.filter(headline__in='abc')

एसक्यूएल समकक्ष:

SELECT ... WHERE id IN (1, 3, 4);
SELECT ... WHERE headline IN ('a', 'b', 'c');

आप शाब्दिक मूल्यों की सूची प्रदान करने के बजाय गतिशील रूप से मूल्यों की सूची का मूल्यांकन करने के लिए एक क्वेरीसेट का उपयोग कर सकते हैं:

inner_qs = Blog.objects.filter(name__contains='Cheddar')
entries = Entry.objects.filter(blog__in=inner_qs)

इस क्वेरी को सबसेलेट स्टेटमेंट के रूप में मूल्यांकन किया जाएगा:

SELECT ... WHERE blog.id IN (SELECT id FROM ... WHERE NAME LIKE '%Cheddar%')

यदि आप लुकअप के मान QuerySet से values() या उसके परिणामस्वरूप पास values_list() करते हैं __in , तो आपको यह सुनिश्चित करने की आवश्यकता है कि आप परिणाम में केवल एक फ़ील्ड निकाल रहे हैं। उदाहरण के लिए, यह काम करेगा (ब्लॉग नामों पर फ़िल्टर करना):

inner_qs = Blog.objects.filter(name__contains='Ch').values('name')
entries = Entry.objects.filter(blog__name__in=inner_qs)

यह उदाहरण एक अपवाद को बढ़ाएगा, क्योंकि आंतरिक क्वेरी दो फ़ील्ड मान निकालने की कोशिश कर रही है, जहां केवल एक ही अपेक्षित है:

# Bad code! Will raise a TypeError.
inner_qs = Blog.objects.filter(name__contains='Ch').values('name', 'id')
entries = Entry.objects.filter(blog__name__in=inner_qs)

प्रदर्शन के विचार

नेस्टेड प्रश्नों का उपयोग करने के बारे में सतर्क रहें और अपने डेटाबेस सर्वर के प्रदर्शन विशेषताओं (यदि संदेह में, बेंचमार्क!) को समझें। कुछ डेटाबेस का समर्थन करता है, सबसे विशेष रूप से MySQL, नेस्टेड प्रश्नों को बहुत अच्छी तरह से अनुकूलित नहीं करता है। यह अधिक कुशल है, उन मामलों में, मूल्यों की सूची निकालने के लिए और फिर दूसरी क्वेरी में पास करें। अर्थात्, एक के बजाय दो प्रश्नों को निष्पादित करें:

values = Blog.objects.filter(
        name__contains='Cheddar').values_list('pk', flat=True)
entries = Entry.objects.filter(blog__in=list(values))

पहली क्वेरी के निष्पादन को बाध्य करने के list() लिए ब्लॉग के चारों ओर कॉल पर ध्यान दें QuerySet । इसके बिना, एक नेस्टेड क्वेरी निष्पादित की जाएगी, क्योंकि क्वेरीसेट आलसी हैं

gt

से अधिक।

उदाहरण:

Entry.objects.filter(id__gt=4)

SQL समकक्ष:

SELECT ... WHERE id > 4;

gte

इससे बड़ा या इसके बराबर।

lt

से कम।

lte

से कम या बराबर।

startswith

केस-सेंसिटिव शुरू-साथ।

उदाहरण:

Entry.objects.filter(headline__startswith='Lennon')

SQL समकक्ष:

SELECT ... WHERE headline LIKE 'Lennon%';

SQLite केस-संवेदी LIKE बयानों का समर्थन नहीं करता है ; SQLite के लिए startswith कार्य करता है istartswith

istartswith

केस-असंवेदनशील शुरू-साथ।

उदाहरण:

Entry.objects.filter(headline__istartswith='Lennon')

SQL समकक्ष:

SELECT ... WHERE headline ILIKE 'Lennon%';

SQLite उपयोगकर्ताओं

SQLite बैकएंड और गैर- ASCII तार का उपयोग करते समय, स्ट्रिंग तुलना के बारे में डेटाबेस नोट पर ध्यान दें

endswith

केस-संवेदी छोर-के साथ।

उदाहरण:

Entry.objects.filter(headline__endswith='Lennon')

SQL समकक्ष:

SELECT ... WHERE headline LIKE '%Lennon';

SQLite उपयोगकर्ताओं

SQLite केस-संवेदी LIKE बयानों का समर्थन नहीं करता है ; SQLite के लिए endswith कार्य करता है iendswith । अधिक के लिए डेटाबेस नोट प्रलेखन देखें ।

iendswith

केस-असंवेदनशील अंत के साथ।

उदाहरण:

Entry.objects.filter(headline__iendswith='Lennon')

SQL समकक्ष:

SELECT ... WHERE headline ILIKE '%Lennon'

SQLite उपयोगकर्ताओं

SQLite बैकएंड और गैर- ASCII तार का उपयोग करते समय, स्ट्रिंग तुलना के बारे में डेटाबेस नोट पर ध्यान दें

range

रेंज टेस्ट (समावेशी)।

उदाहरण:

import datetime
start_date = datetime.date(2005, 1, 1)
end_date = datetime.date(2005, 3, 31)
Entry.objects.filter(pub_date__range=(start_date, end_date))

SQL समकक्ष:

SELECT ... WHERE pub_date BETWEEN '2005-01-01' and '2005-03-31';

आप एसक्यूएल में range कहीं भी उपयोग कर सकते हैं BETWEEN - तिथियों, संख्याओं और यहां तक ​​कि वर्णों के लिए भी।

चेतावनी

किसी DateTimeField दिनांक के साथ फ़िल्टर करने पर अंतिम दिन आइटम शामिल नहीं होंगे, क्योंकि सीमाओं की व्याख्या "दी गई तारीख पर 0 बजे" के रूप में की जाती है। यदि pub_date एक था DateTimeField , तो उपरोक्त अभिव्यक्ति इस एसक्यूएल में बदल जाएगी:

SELECT ... WHERE pub_date BETWEEN '2005-01-01 00:00:00' and '2005-03-31 00:00:00';

आम तौर पर, आप तारीखों और डेटासेट को नहीं मिला सकते हैं।

date

डेटाइम क्षेत्रों के लिए, मान को दिनांक के रूप में रखता है। अतिरिक्त फ़ील्ड लुकअप की अनुमति देता है। दिनांक मान लेता है।

उदाहरण:

Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))

(इस लुकअप के लिए कोई समतुल्य SQL कोड टुकड़ा शामिल नहीं है क्योंकि प्रासंगिक क्वेरी का कार्यान्वयन विभिन्न डेटाबेस इंजनों में भिन्न होता है।

जब USE_TZ है True , फ़िल्टर करने से पहले फ़ील्ड को वर्तमान समय क्षेत्र में बदल दिया जाता है।

year

दिनांक और डेटाटाइम फ़ील्ड के लिए, एक सटीक वर्ष मिलान। अतिरिक्त फ़ील्ड लुकअप की अनुमति देता है। एक पूर्णांक वर्ष लेता है।

उदाहरण:

Entry.objects.filter(pub_date__year=2005)
Entry.objects.filter(pub_date__year__gte=2005)

SQL समकक्ष:

SELECT ... WHERE pub_date BETWEEN '2005-01-01' AND '2005-12-31';
SELECT ... WHERE pub_date >= '2005-01-01';

(प्रत्येक डेटाबेस इंजन के लिए सटीक SQL सिंटैक्स भिन्न होता है।)

जब USE_TZ होता है True , तो फ़िल्टर करने से पहले डेटाटाइम फ़ील्ड वर्तमान समय क्षेत्र में बदल जाती हैं।

month

दिनांक और डेटाटाइम फ़ील्ड के लिए, एक सटीक माह मिलान। अतिरिक्त फ़ील्ड लुकअप की अनुमति देता है। 12 (दिसंबर) के माध्यम से एक पूर्णांक 1 (जनवरी) लेता है।

उदाहरण:

Entry.objects.filter(pub_date__month=12)
Entry.objects.filter(pub_date__month__gte=6)

SQL समकक्ष:

SELECT ... WHERE EXTRACT('month' FROM pub_date) = '12';
SELECT ... WHERE EXTRACT('month' FROM pub_date) >= '6';

(प्रत्येक डेटाबेस इंजन के लिए सटीक SQL सिंटैक्स भिन्न होता है।)

जब USE_TZ होता है True , तो फ़िल्टर करने से पहले डेटाटाइम फ़ील्ड वर्तमान समय क्षेत्र में बदल जाती हैं। इसके लिए डेटाबेस में टाइम ज़ोन परिभाषाएँ आवश्यक हैं ।

day

दिनांक और डेटाटाइम फ़ील्ड के लिए, एक सटीक दिन मिलान। अतिरिक्त फ़ील्ड लुकअप की अनुमति देता है। एक पूर्णांक दिन लेता है।

उदाहरण:

Entry.objects.filter(pub_date__day=3)
Entry.objects.filter(pub_date__day__gte=3)

SQL समकक्ष:

SELECT ... WHERE EXTRACT('day' FROM pub_date) = '3';
SELECT ... WHERE EXTRACT('day' FROM pub_date) >= '3';

(प्रत्येक डेटाबेस इंजन के लिए सटीक SQL सिंटैक्स भिन्न होता है।)

ध्यान दें कि यह माह के तीसरे दिन pub_date के साथ किसी भी रिकॉर्ड से मेल खाएगा, जैसे कि 3 जनवरी, 3 जुलाई, आदि।

जब USE_TZ होता है True , तो फ़िल्टर करने से पहले डेटाटाइम फ़ील्ड वर्तमान समय क्षेत्र में बदल जाती हैं। इसके लिए डेटाबेस में टाइम ज़ोन परिभाषाएँ आवश्यक हैं ।

week

दिनांक और डेटाटाइम फ़ील्ड के लिए, ISO-8601 अनुसार सप्ताह संख्या (1-52 या 53) लौटाएं , अर्थात सप्ताह सोमवार से शुरू होते हैं और पहले सप्ताह में वर्ष का पहला गुरुवार होता है।

उदाहरण:

Entry.objects.filter(pub_date__week=52)
Entry.objects.filter(pub_date__week__gte=32, pub_date__week__lte=38)

(इस लुकअप के लिए कोई समतुल्य SQL कोड टुकड़ा शामिल नहीं है क्योंकि प्रासंगिक क्वेरी का कार्यान्वयन विभिन्न डेटाबेस इंजनों में भिन्न होता है।

जब USE_TZ है True , फ़िल्टर करने से पहले फ़ील्ड को वर्तमान समय क्षेत्र में बदल दिया जाता है।

week_day

दिनांक और डेटाटाइम फ़ील्ड के लिए, 'सप्ताह का दिन' मैच। अतिरिक्त फ़ील्ड लुकअप की अनुमति देता है।

1 (रविवार) से 7 (शनिवार) सप्ताह के दिन का प्रतिनिधित्व करने वाला पूर्णांक मान लेता है।

उदाहरण:

Entry.objects.filter(pub_date__week_day=2)
Entry.objects.filter(pub_date__week_day__gte=2)

(इस लुकअप के लिए कोई समतुल्य SQL कोड टुकड़ा शामिल नहीं है क्योंकि प्रासंगिक क्वेरी का कार्यान्वयन विभिन्न डेटाबेस इंजनों में भिन्न होता है।

ध्यान दें कि यह pub_date उस महीने या सप्ताह के सोमवार (सप्ताह के 2 दिन) पर पड़ने वाले किसी भी रिकॉर्ड से मेल खाएगा , चाहे वह महीना या साल हो। सप्ताह के दिनों को दिन 1 और रविवार को 7 दिन शनिवार के साथ अनुक्रमित किया जाता है।

जब USE_TZ होता है True , तो फ़िल्टर करने से पहले डेटाटाइम फ़ील्ड वर्तमान समय क्षेत्र में बदल जाती हैं। इसके लिए डेटाबेस में टाइम ज़ोन परिभाषाएँ आवश्यक हैं ।

quarter

Django 2.0 में नया:

दिनांक और डेटाटाइम फ़ील्ड के लिए, 'वर्ष का एक चौथाई' मैच। अतिरिक्त फ़ील्ड लुकअप की अनुमति देता है। 1 और 4 के बीच पूर्णांक मान लेता है जो वर्ष की तिमाही का प्रतिनिधित्व करता है।

दूसरी तिमाही में प्रविष्टियाँ प्राप्त करने के लिए उदाहरण (1 अप्रैल से 30 जून):

Entry.objects.filter(pub_date__quarter=2)

(इस लुकअप के लिए कोई समतुल्य SQL कोड टुकड़ा शामिल नहीं है क्योंकि प्रासंगिक क्वेरी का कार्यान्वयन विभिन्न डेटाबेस इंजनों में भिन्न होता है।

जब USE_TZ होता है True , तो फ़िल्टर करने से पहले डेटाटाइम फ़ील्ड वर्तमान समय क्षेत्र में बदल जाती हैं। इसके लिए डेटाबेस में टाइम ज़ोन परिभाषाएँ आवश्यक हैं ।

time

डेटाइम क्षेत्रों के लिए, समय के रूप में मूल्य डाले। अतिरिक्त फ़ील्ड लुकअप की अनुमति देता है। datetime.time मान लेता है ।

उदाहरण:

Entry.objects.filter(pub_date__time=datetime.time(14, 30))
Entry.objects.filter(pub_date__time__range=(datetime.time(8), datetime.time(17)))

(इस लुकअप के लिए कोई समतुल्य SQL कोड टुकड़ा शामिल नहीं है क्योंकि प्रासंगिक क्वेरी का कार्यान्वयन विभिन्न डेटाबेस इंजनों में भिन्न होता है।

जब USE_TZ है True , फ़िल्टर करने से पहले फ़ील्ड को वर्तमान समय क्षेत्र में बदल दिया जाता है।

hour

डेटाइम और टाइम फील्ड के लिए, एक सटीक घंटे का मैच। अतिरिक्त फ़ील्ड लुकअप की अनुमति देता है। 0 और 23 के बीच पूर्णांक बनाता है।

उदाहरण:

Event.objects.filter(timestamp__hour=23)
Event.objects.filter(time__hour=5)
Event.objects.filter(timestamp__hour__gte=12)

SQL समकक्ष:

SELECT ... WHERE EXTRACT('hour' FROM timestamp) = '23';
SELECT ... WHERE EXTRACT('hour' FROM time) = '5';
SELECT ... WHERE EXTRACT('hour' FROM timestamp) >= '12';

(प्रत्येक डेटाबेस इंजन के लिए सटीक SQL सिंटैक्स भिन्न होता है।)

Datetime क्षेत्रों के लिए, जब USE_TZ है True , मूल्यों वर्तमान समय क्षेत्र को छानने से पहले बदल रहे हैं।

minute

डेटाइम और टाइम फील्ड के लिए, एक सटीक मिनट मैच। अतिरिक्त फ़ील्ड लुकअप की अनुमति देता है। 0 और 59 के बीच पूर्णांक बनाता है।

उदाहरण:

Event.objects.filter(timestamp__minute=29)
Event.objects.filter(time__minute=46)
Event.objects.filter(timestamp__minute__gte=29)

SQL समकक्ष:

SELECT ... WHERE EXTRACT('minute' FROM timestamp) = '29';
SELECT ... WHERE EXTRACT('minute' FROM time) = '46';
SELECT ... WHERE EXTRACT('minute' FROM timestamp) >= '29';

(प्रत्येक डेटाबेस इंजन के लिए सटीक SQL सिंटैक्स भिन्न होता है।)

Datetime क्षेत्रों के लिए, जब USE_TZ है True , मूल्यों वर्तमान समय क्षेत्र को छानने से पहले बदल रहे हैं।

second

डेटाइम और टाइम फील्ड के लिए, एक सटीक दूसरा मैच। अतिरिक्त फ़ील्ड लुकअप की अनुमति देता है। 0 और 59 के बीच पूर्णांक बनाता है।

उदाहरण:

Event.objects.filter(timestamp__second=31)
Event.objects.filter(time__second=2)
Event.objects.filter(timestamp__second__gte=31)

SQL समकक्ष:

SELECT ... WHERE EXTRACT('second' FROM timestamp) = '31';
SELECT ... WHERE EXTRACT('second' FROM time) = '2';
SELECT ... WHERE EXTRACT('second' FROM timestamp) >= '31';

(प्रत्येक डेटाबेस इंजन के लिए सटीक SQL सिंटैक्स भिन्न होता है।)

Datetime क्षेत्रों के लिए, जब USE_TZ है True , मूल्यों वर्तमान समय क्षेत्र को छानने से पहले बदल रहे हैं।

isnull

ले जाता है या तो True या False , जिनमें से एसक्यूएल क्वेरी से संबंधित हैं IS NULL और IS NOT NULL क्रमश:।

उदाहरण:

Entry.objects.filter(pub_date__isnull=True)

SQL समकक्ष:

SELECT ... WHERE pub_date IS NULL;

regex

केस-सेंसिटिव रेगुलर एक्सप्रेशन मैच।

नियमित अभिव्यक्ति सिंटैक्स डेटाबेस बैकएंड के उपयोग में है। SQLite के मामले में, जो नियमित अभिव्यक्ति समर्थन में नहीं बनाया गया है, यह सुविधा एक (पायथन) उपयोगकर्ता द्वारा परिभाषित REGEXP फ़ंक्शन द्वारा प्रदान की जाती है, और नियमित अभिव्यक्ति सिंटैक्स इसलिए है कि पायथन re मॉड्यूल है।

उदाहरण:

Entry.objects.get(title__regex=r'^(An?|The) +')

एसक्यूएल समकक्ष:

SELECT ... WHERE title REGEXP BINARY '^(An?|The) +'; -- MySQL

SELECT ... WHERE REGEXP_LIKE(title, '^(An?|The) +', 'c'); -- Oracle

SELECT ... WHERE title ~ '^(An?|The) +'; -- PostgreSQL

SELECT ... WHERE title REGEXP '^(An?|The) +'; -- SQLite

नियमित अभिव्यक्ति वाक्य रचना में पारित r'foo' करने के 'foo' लिए कच्चे तार (जैसे, के बजाय ) का उपयोग करने की सिफारिश की जाती है।

iregex

केस-असंवेदनशील नियमित अभिव्यक्ति मैच।

उदाहरण:

Entry.objects.get(title__iregex=r'^(an?|the) +')

एसक्यूएल समकक्ष:

SELECT ... WHERE title REGEXP '^(an?|the) +'; -- MySQL

SELECT ... WHERE REGEXP_LIKE(title, '^(an?|the) +', 'i'); -- Oracle

SELECT ... WHERE title ~* '^(an?|the) +'; -- PostgreSQL

SELECT ... WHERE title REGEXP '(?i)^(an?|the) +'; -- SQLite

एकत्रीकरण कार्य

Django django.db.models मॉड्यूल में निम्नलिखित एकत्रीकरण कार्य प्रदान करता है । इन समग्र कार्यों का उपयोग करने के तरीके के विवरण के लिए, एकत्रीकरण पर विषय मार्गदर्शिका देखें। Aggregate अपने समुच्चय बनाने का तरीका जानने के लिए दस्तावेज़ीकरण देखें ।

चेतावनी

SQLite बॉक्स से बाहर दिनांक / समय फ़ील्ड पर एकत्रीकरण को संभाल नहीं सकता है। इसका कारण यह है कि SQLite में कोई मूल दिनांक / समय फ़ील्ड नहीं हैं और Django वर्तमान में पाठ फ़ील्ड का उपयोग करके इन सुविधाओं का अनुकरण करता है। SQLite में दिनांक / समय फ़ील्ड पर एकत्रीकरण का उपयोग करने का प्रयास करेगा NotImplementedError

ध्यान दें

None जब एक खाली के साथ प्रयोग किया जाता है तो एकत्रीकरण कार्य वापस आते हैं QuerySet । उदाहरण के लिए, Sum एकत्रीकरण फ़ंक्शन None के बजाय 0 अगर QuerySet कोई प्रविष्टियां नहीं हैं। एक अपवाद है Count , जो वापसी करता 0 है, तो QuerySet खाली है।

सभी समुच्चय में निम्नलिखित पैरामीटर सामान्य हैं:

expression

एक स्ट्रिंग जो मॉडल पर एक क्षेत्र, या एक क्वेरी अभिव्यक्ति का संदर्भ देता है ।

output_field

एक वैकल्पिक तर्क जो रिटर्न मान के मॉडल क्षेत्र का प्रतिनिधित्व करता है

ध्यान दें

कई फ़ील्ड प्रकारों का संयोजन करते समय, Django केवल यह निर्धारित कर सकता है कि output_field क्या सभी फ़ील्ड एक ही प्रकार के हैं। अन्यथा, आपको output_field खुद को प्रदान करना होगा ।

filter

Django 2.0 में नया:

एक वैकल्पिक Q object जो कि एकत्रित पंक्तियों को फ़िल्टर करने के लिए उपयोग किया जाता है।

उदाहरण उपयोग के लिए एनोटेशन पर सशर्त एकत्रीकरण और फ़िल्टरिंग देखें ।

**extra

कीवर्ड तर्क जो एग्रीगेट द्वारा उत्पन्न SQL के लिए अतिरिक्त संदर्भ प्रदान कर सकते हैं।

Avg

class Avg(expression, output_field=FloatField(), filter=None, **extra) [source]

दिए गए व्यंजक का माध्य मान लौटाता है, जो तब तक संख्यात्मक होना चाहिए जब तक कि आप एक अलग निर्दिष्ट न करें output_field

  • डिफ़ॉल्ट उपनाम: <field>__avg
  • वापसी प्रकार: float (या जो कुछ भी output_field निर्दिष्ट किया गया है उसका प्रकार )

Count

class Count(expression, distinct=False, filter=None, **extra) [source]

प्रदान की गई अभिव्यक्ति के माध्यम से संबंधित वस्तुओं की संख्या लौटाती है।

  • डिफ़ॉल्ट उपनाम: <field>__count
  • वापसी प्रकार: int

एक वैकल्पिक तर्क है:

distinct

यदि distinct=True , गणना में केवल अनन्य उदाहरण शामिल होंगे। यह SQL के बराबर है COUNT(DISTINCT <field>) । डिफ़ॉल्ट मान है False

Max

class Max(expression, output_field=None, filter=None, **extra) [source]

दिए गए अभिव्यक्ति का अधिकतम मूल्य लौटाता है।

  • डिफ़ॉल्ट उपनाम: <field>__max
  • वापसी प्रकार: इनपुट क्षेत्र के समान, या output_field यदि आपूर्ति की गई हो

Min

class Min(expression, output_field=None, filter=None, **extra) [source]

दिए गए अभिव्यक्ति का न्यूनतम मूल्य लौटाता है।

  • डिफ़ॉल्ट उपनाम: <field>__min
  • वापसी प्रकार: इनपुट क्षेत्र के समान, या output_field यदि आपूर्ति की गई हो

StdDev

class StdDev(expression, sample=False, filter=None, **extra) [source]

प्रदान की गई अभिव्यक्ति में डेटा का मानक विचलन लौटाता है।

  • डिफ़ॉल्ट उपनाम: <field>__stddev
  • वापसी प्रकार: float

एक वैकल्पिक तर्क है:

sample

डिफ़ॉल्ट रूप से, StdDev जनसंख्या मानक विचलन लौटाता है। हालांकि, अगर sample=True , वापसी मूल्य नमूना मानक विचलन होगा।

SQLite

SQLite StdDev बॉक्स से बाहर प्रदान नहीं करता है । एक कार्यान्वयन SQLite के लिए एक विस्तार मॉड्यूल के रूप में उपलब्ध है। इस एक्सटेंशन को प्राप्त करने और स्थापित करने के निर्देशों के लिए SQlite प्रलेखन से परामर्श करें ।

Sum

class Sum(expression, output_field=None, filter=None, **extra) [source]

दिए गए अभिव्यक्ति के सभी मूल्यों के योग की गणना करता है।

  • डिफ़ॉल्ट उपनाम: <field>__sum
  • वापसी प्रकार: इनपुट क्षेत्र के समान, या output_field यदि आपूर्ति की गई हो

Variance

class Variance(expression, sample=False, filter=None, **extra) [source]

प्रदान की गई अभिव्यक्ति में डेटा के विचरण को लौटाता है।

  • डिफ़ॉल्ट उपनाम: <field>__variance
  • वापसी प्रकार: float

एक वैकल्पिक तर्क है:

sample

डिफ़ॉल्ट रूप से, Variance जनसंख्या विचरण लौटाता है। हालांकि, अगर sample=True , वापसी मूल्य नमूना विचरण होगा।

SQLite

SQLite Variance बॉक्स से बाहर प्रदान नहीं करता है । एक कार्यान्वयन SQLite के लिए एक विस्तार मॉड्यूल के रूप में उपलब्ध है। इस एक्सटेंशन को प्राप्त करने और स्थापित करने के निर्देशों के लिए SQlite प्रलेखन से परामर्श करें ।

Q() वस्तुओं

class Q [source]

एक Q() वस्तु, एक तरह F वस्तु, एक अजगर उद्देश्य यह है कि डेटाबेस से संबंधित कार्यों में इस्तेमाल किया जा सकता है में एक एसक्यूएल अभिव्यक्ति समाहित।

सामान्य तौर पर, Q() objects शर्तों को परिभाषित करना और पुन: उपयोग करना संभव बनाते हैं। यह ( ) और ( ) ऑपरेटरों का उपयोग करके जटिल डेटाबेस प्रश्नों के निर्माण की अनुमति देता है ; विशेष रूप से, यह अन्यथा उपयोग करने के लिए संभव नहीं है । | OR & AND OR QuerySets

Prefetch() वस्तुओं

class Prefetch(lookup, queryset=None, to_attr=None) [source]

Prefetch() वस्तु के संचालन को नियंत्रित करने के लिए किया जा सकता prefetch_related()

lookup तर्क संबंधों का पालन करने का वर्णन करता है और स्ट्रिंग आधारित खोज के लिए पारित कर दिया के रूप में ही काम करता है prefetch_related() । उदाहरण के लिए:

>>> from django.db.models import Prefetch
>>> Question.objects.prefetch_related(Prefetch('choice_set')).get().choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
# This will only execute two queries regardless of the number of Question
# and Choice objects.
>>> Question.objects.prefetch_related(Prefetch('choice_set')).all()
<QuerySet [<Question: What's up?>]>

queryset तर्क एक आधार की आपूर्ति QuerySet को देखते हुए देखने के लिए। यह प्रीफ़ैच ऑपरेशन को आगे फ़िल्टर करने के लिए, या select_related() प्रीफ़ेट किए गए संबंध से कॉल करने के लिए उपयोगी है , इसलिए प्रश्नों की संख्या को कम करना भी:

>>> voted_choices = Choice.objects.filter(votes__gt=0)
>>> voted_choices
<QuerySet [<Choice: The sky>]>
>>> prefetch = Prefetch('choice_set', queryset=voted_choices)
>>> Question.objects.prefetch_related(prefetch).get().choice_set.all()
<QuerySet [<Choice: The sky>]>

to_attr तर्क कस्टम विशेषता को प्रीफ़ेच आपरेशन के परिणाम सेट:

>>> prefetch = Prefetch('choice_set', queryset=voted_choices, to_attr='voted_choices')
>>> Question.objects.prefetch_related(prefetch).get().voted_choices
<QuerySet [<Choice: The sky>]>
>>> Question.objects.prefetch_related(prefetch).get().choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>

ध्यान दें

to_attr प्रीफ़ेट किए गए परिणाम का उपयोग करते समय एक सूची में संग्रहीत किया जाता है। यह पारंपरिक prefetch_related कॉल पर एक महत्वपूर्ण गति सुधार प्रदान कर सकता है जो एक QuerySet उदाहरण के भीतर कैश्ड परिणाम को संग्रहीत करता है ।

दिए गए लुकअप को मॉडल इंस्टेंसेस के चलने योग्य पर प्रीफ़ेट करता है। यह कोड में उपयोगी है जो मॉडल के उदाहरणों की एक सूची प्राप्त करता है जैसा कि एक के विपरीत QuerySet ; उदाहरण के लिए, जब कोई कैश से मॉडल ला रहा है या उन्हें मैन्युअल रूप से इंस्टेंट कर रहा है।

मॉडल इंस्टेंसेस के एक चलने योग्य पास करें (जो सभी एक ही वर्ग के होने चाहिए) और वे लुकअप या Prefetch ऑब्जेक्ट जो आप के लिए प्रीफेच करना चाहते हैं। उदाहरण के लिए:

>>> from django.db.models import prefetch_related_objects
>>> restaurants = fetch_top_restaurants_from_cache()  # A list of Restaurants
>>> prefetch_related_objects(restaurants, 'pizzas__toppings')

FilteredRelation() वस्तुओं

Django 2.0 में नया:
class FilteredRelation(relation_name, *, condition=Q()) [source]
relation_name

उस फ़ील्ड का नाम, जिस पर आप संबंध फ़िल्टर करना चाहते हैं।

condition

एक Q वस्तु को छानने नियंत्रित करने के लिए।

FilteredRelation साथ प्रयोग किया जाता है annotate() एक बनाने के लिए ON जब एक खंड JOIN किया जाता है। यह डिफ़ॉल्ट संबंध पर काम नहीं करता है, लेकिन एनोटेशन नाम पर ( pizzas_vegetarian नीचे उदाहरण में)।

उदाहरण के लिए, उन रेस्तरां को खोजने के लिए जिनके 'mozzarella' नाम में शाकाहारी पिज्जा हैं :

>>> from django.db.models import FilteredRelation, Q
>>> Restaurant.objects.annotate(
...    pizzas_vegetarian=FilteredRelation(
...        'pizzas', condition=Q(pizzas__vegetarian=True),
...    ),
... ).filter(pizzas_vegetarian__name__icontains='mozzarella')

यदि बड़ी संख्या में पिज्जा हैं, तो यह क्वेरी इससे बेहतर प्रदर्शन करती है:

>>> Restaurant.objects.filter(
...     pizzas__vegetarian=True,
...     pizzas__name__icontains='mozzarella',
... )

क्योंकि WHERE पहले क्वेरी के क्लॉज में फ़िल्टरिंग केवल शाकाहारी पिज्जा पर काम करेगा।

FilteredRelation समर्थन नहीं करता है:

  • ऐसी स्थितियां जो संबंधपरक क्षेत्रों को फैलाती हैं। उदाहरण के लिए:

    >>> Restaurant.objects.annotate(
    ...    pizzas_with_toppings_startswith_n=FilteredRelation(
    ...        'pizzas__toppings',
    ...        condition=Q(pizzas__toppings__name__startswith='n'),
    ...    ),
    ... )
    Traceback (most recent call last):
    ...
    ValueError: FilteredRelation's condition doesn't support nested relations (got 'pizzas__toppings__name__startswith').
    
  • only() और prefetch_related()
  • एक GenericForeignKey मूल मॉडल से विरासत में मिला।

Original text