Django में / क्वेरी में नहीं


100

मैं यह पता लगाने की कोशिश कर रहा हूं कि django में 'क्वेरी' शैली क्वेरी कैसे लिखनी है। उदाहरण के लिए, मैं जिस क्वेरी संरचना के बारे में सोच रहा हूं वह इस तरह दिखाई देगी।

select table1.* 
from table1
where table1.id not in 
(
  select table2.key_to_table1
  from table2 
  where table2.id = some_parm 
)

Django सिंटैक्स को table1 और table2 कहे जाने वाले मॉडल की तरह क्या दिखेगा?

जवाबों:


164
table1.objects.exclude(id__in=
    table2.objects.filter(your_condition).values_list('id', flat=True))

बहिष्कृत फ़ंक्शन उस Notऑपरेटर की तरह काम करता है जिसे आप पूछ रहे हैं। विशेषता क्वेरी को एक स्तर सूची के रूप में वापस करने के flat = Trueलिए कहती है । तो ... अंत में आप तालिका 2 से एक सूची प्राप्त कर रहे हैं , जिसे आप उपयोगकर्ता को उस स्थिति को परिभाषित करने जा रहे हैं, जिसे बहिष्कृत फ़ंक्शन द्वारा अस्वीकार कर दिया जाएगा।table2value_listIDstable1


3
मुझे सूची निर्माता [टेबल 2 ...] -> सूची (टेबल 2 ...) से भी परेशानी थी, मेरे लिए काम किया।
रिकाडा

3
सुधार: table1.objects.exclude (id__in = table2.objects.filter (your_condition) .values_list ('id', सपाट = सत्य))
रिचर्ड

1
इस समाधान का उपयोग करने की कोशिश कर रहा था और एक समस्या में भाग गया, इसलिए यदि यह किसी और के साथ होता है ... तो Objs=Tbl1.objects.filter(...); IDs=Objs.values_list('id', flat=True); Objs.delete(); Tbl2.objects.filter(id__in=IDs')यह काम नहीं किया क्योंकि आईडी वास्तव में एक क्वेरीसैट ऑब्जेक्ट है। जब मैंने इससे निकली पंक्तियों को हटा दिया, तो यह अन्य प्रश्नों के साथ काम नहीं करती थी। इसका हल है Tbl2.objects.filter(id__in=list(IDs))- इसे सूची में बदल दें
डाकुसन

1
संदर्भ के आधार पर, यदि फ़िल्टर " annotate()काउंटिंग (xx) == yy" की तरह है, तो इसका उपयोग करने के लिए 100x से अधिक तेज़ है (समय-समय पर मुझे 1.0497902309998608 बनाम 0.00514069400014705)
Pons

10

इन मॉडलों के साथ:

class table1(models.Model):
    field1 = models.CharField(max_length=10)      # a dummy field

class table2(models.Model):
    key_to_table1 = models.ForeignKey(table1)

आपको वह प्राप्त करना चाहिए जो आप उपयोग करना चाहते हैं:

table1.objects.exclude(table2=some_param)

1
यह अभी भी आप संभावित रूप से डीबी से अनावश्यक रूप से बहुत सारे रिकॉर्ड खींच रहा है।
जय टेलर

5
table1.objects.extra(where=["table1.id NOT IN (SELECT table2.key_to_table1 FROM table2 WHERE table2.id = some_parm)"])

1

आप Django प्रश्नों के लिए एक कस्टम लुकअप लिख सकते हैं:

से प्रलेखन : "। एक साधारण कस्टम देखने के साथ आइए शुरू हम एक कस्टम देखने लिखेंगे ne जो के विपरीत काम करता है सटीकAuthor.objects.filter (name__ne = 'जैक') एसक्यूएल करने के लिए अनुवाद कर देगा: "author"."name" <> 'Jack'"

from django.db.models import Lookup

class NotEqual(Lookup):
    lookup_name = 'ne'

    def as_sql(self, compiler, connection):
        lhs, lhs_params = self.process_lhs(compiler, connection)
        rhs, rhs_params = self.process_rhs(compiler, connection)
        params = lhs_params + rhs_params
        return '%s <> %s' % (lhs, rhs), params

-16
[o1 for o1 in table1.objects.all() if o1.id not in [o2.id for o2 in table2.objects.filter(id=some_parm)]]

या और अच्छा

not_in_ids = [obj.id for obj in table2.objects.filter(id=some_parm)]
selected_objects = [obj for obj in table1.objects.iterator() if obj.id not in not_in_ids]

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