2010-12-22 23 views
49

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

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) 

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

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

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

या सिर्फ अगर self.role.id पीकेएस की एक सूची नहीं है::

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

उत्तर

66

आप कुछ इस तरह की कोशिश की है। आपको बस यह सुनिश्चित करना होगा कि यह एक सूची है। दूसरा उदाहरण, trigger_roles__id__exact की जांच करना एक बेहतर समाधान है।

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

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

+5

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

+0

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

4

व्यक्तित्व लगभग सही पहला उदाहरण के साथ है

7

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

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

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

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

संबंधित मुद्दे