किसी क्वेरी में खाली या NULL नामों के लिए फ़िल्टरिंग


463

मेरे पास है first_name, last_nameऔर alias(वैकल्पिक) जिसे मुझे खोजना है। इसलिए, मुझे उन सभी नामों को देने के लिए एक क्वेरी की आवश्यकता है जिनके पास एक उपनाम सेट है।

केवल अगर मैं कर सकता था:

Name.objects.filter(alias!="")

तो, उपरोक्त के बराबर क्या है?

जवाबों:


839

आप ऐसा कर सकते हैं:

Name.objects.exclude(alias__isnull=True)

यदि आपको अशक्त मानों और रिक्त तारों को बाहर करने की आवश्यकता है , तो ऐसा करने का पसंदीदा तरीका शर्तों की एक साथ श्रृंखला करना है:

Name.objects.exclude(alias__isnull=True).exclude(alias__exact='')

इन तरीकों को एक साथ मिलाकर मूल रूप से प्रत्येक स्थिति की स्वतंत्र रूप से जांच की जाती है: उपरोक्त उदाहरण में, हम उन पंक्तियों को बाहर करते हैं जहां aliasया तो नल या खाली स्ट्रिंग है, इसलिए आपको सभी Nameऑब्जेक्ट मिलते हैं जिनमें एक शून्य, शून्य-खाली aliasफ़ील्ड नहीं है। उत्पन्न SQL कुछ इस तरह दिखेगा:

SELECT * FROM Name WHERE alias IS NOT NULL AND alias != ""

आप एकल कॉल करने के लिए कई तर्क भी दे सकते हैं exclude, जो यह सुनिश्चित करेगा कि केवल ऐसी वस्तुएं जो हर शर्त को पूरा करती हैं:

Name.objects.exclude(some_field=True, other_field=True)

यहां, वे पंक्तियाँ जिनमें some_field और other_field सत्य हैं को बाहर रखा गया है, इसलिए हमें वे सभी पंक्तियाँ मिलती हैं जहाँ दोनों क्षेत्र सत्य नहीं हैं। उत्पन्न SQL कोड इस तरह दिखेगा:

SELECT * FROM Name WHERE NOT (some_field = TRUE AND other_field = TRUE)

वैकल्पिक रूप से, यदि आपका तर्क इससे अधिक जटिल है, तो आप Django के Q ऑब्जेक्ट का उपयोग कर सकते हैं :

from django.db.models import Q
Name.objects.exclude(Q(alias__isnull=True) | Q(alias__exact=''))

अधिक जानकारी के लिए इस पृष्ठ और इस पृष्ठ को Django डॉक्स में देखें।

एक तरफ के रूप में: मेरे SQL उदाहरण सिर्फ एक सादृश्य हैं - वास्तविक उत्पन्न SQL कोड शायद अलग दिखेंगे। आप एक गहरी समझ प्राप्त करेंगे कि Django क्वेरी वास्तव में SQL द्वारा उत्पन्न कैसे काम करती है।


5
मेरा मानना ​​है कि आपका संपादन गलत है: चेनिंग फ़िल्टर स्वचालित रूप से एक SQL नहीं बनाता है OR(केवल इस मामले में), यह एक SQL बनाता है AND। संदर्भ के लिए इस पृष्ठ को देखें: docs.djangoproject.com/en/dev/topics/db/queries/… चैनिंग का लाभ यह है कि आप मिश्रित क्वेरी स्थितियों को मिश्रित excludeऔर filterमॉडल कर सकते हैं। यदि आप एक वास्तविक एसक्यूएल का मॉडल बनाना चाहते हैं, तो आपको ORएक Django Q ऑब्जेक्ट का उपयोग करना चाहिए: docs.djangoproject.com/en/dev/topics/db/queries/… कृपया इसे संपादित करने के लिए अपने एडिट को संपादित करें, क्योंकि इसका उत्तर गंभीर रूप से भ्रामक है क्योंकि यह खड़ा है ।
शीजी

1
@shezi: मेरा मतलब है कि यह एक सादृश्य के रूप में अधिक है - मेरा मतलब यह नहीं था कि वास्तविक SQL कोड ORशर्तों का उपयोग करने के लिए गारंटी है । मैं अपना उत्तर स्पष्ट करने के लिए संपादित करूँगा।
साशा चोडगोव

1
ध्यान रखें कि इस तर्क का प्रतिनिधित्व करने के लिए अलग-अलग तरीके हैं - उदाहरण के लिए, NOT (A AND B)बराबर है NOT A OR NOT B। मुझे लगता है कि चीजों को नए Django डेवलपर्स के लिए भ्रामक बनाता है जो एसक्यूएल को जानते हैं लेकिन ओआरएम से अपरिचित हैं।
साशा चोडगोव

3
मुझे पता है कि मॉर्गन का नियम है, और यह मेरी बात बिल्कुल सही है: आपका उदाहरण केवल इसलिए काम करता है क्योंकि यह ANDपहली क्वेरी में ORउपयोग करने के लिए लाभ उठाता है क्योंकि आप उपयोग कर रहे हैं exclude। सामान्य स्थिति में, संभवतः अ को सही तरीके से चेंज करना अधिक सही है THEN, अर्थात exclude(A) THEN exclude(B)। ऊपर की कठोर भाषा के बारे में क्षमा करें। आपका जवाब वास्तव में अच्छा है, लेकिन मैं नए डेवलपर्स के बारे में चिंतित हूं जो आपका जवाब भी आम तौर पर ले रहा है।
shezi

2
@ शीज़ी: काफी फेयर। मैं मानता हूं कि इसे Django के संदर्भ में सोचना बेहतर है और SQL शब्दों में नहीं, मैंने बस सोचा था कि प्रस्तुत करने के संदर्भ में chaining ANDऔर ORSQL पृष्ठभूमि से Django में आने वाले किसी व्यक्ति के लिए उपयोगी हो सकता है। Django की गहरी समझ के लिए, मुझे लगता है कि डॉक्स मुझसे बेहतर काम कर सकते हैं।
साशा चोडगोव

49
Name.objects.filter(alias__gt='',alias__isnull=False)

2
मुझे यकीन नहीं है, लेकिन मुझे लगता है कि alias__isnull=Falseस्थिति बेमानी है। यदि फ़ील्ड Nullनिश्चित रूप से है, तो इसे पहले खंड द्वारा बाहर रखा जाएगा?
बोबले

अपनी पूर्व टिप्पणी / प्रश्न के अलावा, मुझे लगता है कि यहां सकारात्मक तर्क कुछ अन्य उत्तरों की तुलना में आसान है।
बोबले

@ याकूब जो डेटाबेस के कार्यान्वयन पर निर्भर करेगा - ऑर्डर
wpercy

alias__gtकेवल एक चीज जो JSON प्रकार कॉलम के लिए काम करती थी, जहां मैं JSON से खाली तारों को बाहर करना चाहता था {'something:''}। इसलिए वर्किंग सिंटैक्स है:jsoncolumnname__something__gt=''
bartgras

38

सबसे पहले, Django डॉक्स दृढ़ता से स्ट्रिंग-आधारित फ़ील्ड जैसे कि CharField या TextField के लिए NULL मान का उपयोग नहीं करने की सलाह देते हैं। स्पष्टीकरण के लिए प्रलेखन पढ़ें:

https://docs.djangoproject.com/en/dev/ref/models/fields/#null

समाधान: आप क्वेरीस के तरीकों पर एक साथ श्रृंखला बना सकते हैं, मुझे लगता है। इसे इस्तेमाल करे:

Name.objects.exclude(alias__isnull=True).exclude(alias="")

आपको वह सेट देना चाहिए जिसकी आप तलाश कर रहे हैं।


5

Django 1.8 से,

from django.db.models.functions import Length

Name.objects.annotate(alias_length=Length('alias')).filter(alias_length__gt=0)

5
ऐसा लगता है जैसे "कुछ आप कर सकते हैं", कुछ ऐसा नहीं जो आपको करना चाहिए । यह दो सरल जाँचों पर क्वेरी की जटिलता को काफी कम कर देता है।
ओली

3

उपयोग करते समय सामान्य गलतियों से बचने के लिए exclude, याद रखें:

आप एक बहिष्कृत () ब्लॉक की तरह कई शर्तें नहीं जोड़ सकते । कई शर्तों को बाहर करने के लिए, आपको कई बहिष्कृत () का उपयोग करना होगाfilter

उदाहरण

गलत :

User.objects.filter (email='example@example.com ')। बाहर करें (profile__nick_name =' ', profile__avt =' ')

सही करें :

User.objects.filter (email='example@example.com ')। को बाहर (profile__nick_name =' ')। को बाहर (profile__avt =' ')


0

आप बस यह कर सकते हैं:

Name.objects.exclude(alias="").exclude(alias=None)

यह वास्तव में सिर्फ इतना आसान है। filterमिलान करने के लिए उपयोग किया जाता है और excludeसब कुछ मैच करने के लिए होता है लेकिन यह क्या निर्दिष्ट करता है। यह SQL में मूल्यांकन करेगा NOT alias='' AND alias IS NOT NULL


यह गलत है। सवाल खाली ( alias="") और NULL ( alias=None) उपनामों को क्वेरी से बाहर करने का है। तुम्हारे साथ उदाहरण शामिल होंगे Name(alias=None)
डेमन

@ एडमोन - मैं जवाब दे रहा था, .filter(alias!="")लेकिन शीर्षक नहीं के बराबर । मैंने अपना उत्तर संपादित कर दिया है। हालाँकि, वर्ण फ़ील्ड NULL मानों की अनुमति नहीं देनी चाहिए और एक गैर-मान के लिए खाली स्ट्रिंग का उपयोग करना चाहिए (सम्मेलन के अनुसार)।
टिम टिस्डल

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.