Django में कई-से-कई फ़िल्टर शामिल हैं


90

मैं कई-कई संबंधों के माध्यम से वस्तुओं का एक गुच्छा छानने की कोशिश कर रहा हूं। क्योंकि trigger_rolesफ़ील्ड में कई प्रविष्टियाँ हो सकती हैं जिन्हें मैंने containsफ़िल्टर करने की कोशिश की । लेकिन जैसा कि इसे स्ट्रिंग्स के साथ उपयोग करने के लिए डिज़ाइन किया गया है, मैं बहुत असहाय हूं कि मुझे इस संबंध को कैसे फ़िल्टर करना चाहिए (आप values_list()एटीएम को अनदेखा कर सकते हैं ।)।

यह फ़ंक्शन उपयोगकर्ता प्रोफ़ाइल से जुड़ा है:

def getVisiblePackages(self):
    visiblePackages = {}   
    for product in self.products.all():
        moduleDict = {}
        for module in product.module_set.all():
            pkgList = []
            involvedStatus = module.workflow_set.filter(trigger_roles__contains=self.role.id,allowed=True).values_list('current_state', flat=True)

मेरा वर्कफ़्लो मॉडल इस तरह दिखता है (सरलीकृत):

class Workflow(models.Model):
    module = models.ForeignKey(Module)
    current_state = models.ForeignKey(Status)
    next_state = models.ForeignKey(Status)
    allowed = models.BooleanField(default=False)
    involved_roles = models.ManyToManyField(Role, blank=True, null=True)
    trigger_roles = models.ManyToManyField(Role, blank=True, null=True)

यद्यपि समाधान सरल हो सकता है, मेरा मस्तिष्क मुझे नहीं बताएगा।

आपकी सहायता के लिए धन्यवाद।

जवाबों:


110

क्या आपने कुछ इस तरह की कोशिश की है:

module.workflow_set.filter(trigger_roles__in=[self.role], allowed=True)

या बस अगर self.role.idpks की सूची नहीं है:

module.workflow_set.filter(trigger_roles__id__exact=self.role.id, allowed=True)

1
वह काम नहीं लगता है। जैसा कि self.role.id सिर्फ एक int है और ट्रिगर_roles उनमें से एक सूची है, मुझे इनवर्ट की आवश्यकता होगी, जैसे कि इसमें समाहित है लेकिन जैसा कि मुझे पता चला है, इसमें केवल स्ट्रिंग्स के लिए है।
ग्रेव_जंपर

8
दूसरा उदाहरण काम करना चाहिए । यदि मान self.role.idट्रिगर भूमिकाओं में से एक है, तो उस फ़िल्टर को उन सभी वर्कफ़्लोज़ को खींचना चाहिए जहाँ ट्रिगर भूमिकाओं में से एक मान है self.role.id। मूल रूप से यह बिल्कुल "समाहित" फ़ंक्शन की तरह व्यवहार करेगा। जब तक हम सब कुछ याद नहीं कर रहे हैं।
जॉर्डन रीटर

@ जोर्डन रेटर: "समाहित" को एसक्यूएल में "जैसे" में बदल दिया जाता है जो ओपी नहीं चाहता है और मुझे लगता है कि वह पहले से ही इस बात को इंगित करता है, दूसरे हाथ में "सटीक" को "=" या "ए" में बदल दिया जाता है जो कि है यहाँ विचार करें।
मौद

@Grave_Jumper: यहां एक नज़र डालें ( djangoproject.com/documentation/models/many_to_many ) आप कई उदाहरण देख सकते हैं जब कईमोटनी फील्ड के साथ काम करते हैं, तो उम्मीद है कि यह आपकी मदद कर सकता है, अगर मेरा जवाब नहीं है :)
mouad

1
aww .. क्षमा करें आपका दूसरा समाधान अच्छी तरह से काम करता है :) मेरी तरफ से थोड़ा सा मिस कॉन्फ़िगरेशन था। धन्यवाद दोस्तों इससे मेरा दिन बच गया ;-)
Grave_Jumper

19

इसे प्राप्त करने के लिए सबसे सरल दृष्टिकोण पूरे उदाहरण (आईडी के बजाय) में समानता के लिए जाँच करना होगा ManyToManyField। ऐसा लगता है कि उदाहरण कई संबंधों के लिए कई के अंदर है। उदाहरण:

module.workflow_set.filter(trigger_roles=self.role, allowed=True)

7

मुझे पता है कि यह एक पुराना सवाल है, लेकिन ऐसा लग रहा है कि ओपी को कभी वह जवाब नहीं मिला, जिसकी उसे तलाश थी। यदि आपके पास ManyToManyFields के दो सेट हैं जिनकी आप तुलना करना चाहते हैं, तो चाल __inऑपरेटर का उपयोग करना है, नहीं contains। उदाहरण के लिए, यदि आपके पास फ़ील्ड पर "Group" से "Group" के साथ एक "इवेंट" मॉडल है eventgroups, और आपका उपयोगकर्ता मॉडल (स्पष्ट रूप से) समूह से जुड़ता है, तो आप इस तरह क्वेरी कर सकते हैं:

Event.objects.filter(eventgroups__in=u.groups.all())


4

पहले उदाहरण के साथ विलक्षणता लगभग सही है। आपको बस यह सुनिश्चित करने की आवश्यकता है कि यह एक सूची है। दूसरा उदाहरण, जाँच trigger_roles__id__exactएक बेहतर समाधान है।

module.workflow_set.filter(trigger_roles__in=[self.role.id],allowed=True)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.