Django กรองแบบกลุ่มต่อกลุ่มด้วยประกอบด้วย


90

ฉันพยายามกรองวัตถุจำนวนมากผ่านความสัมพันธ์แบบกลุ่มต่อกลุ่ม เนื่องจากtrigger_rolesช่องอาจมีหลายรายการฉันจึงลองใช้containsตัวกรอง แต่ตามที่ออกแบบมาเพื่อใช้กับสตริงฉันค่อนข้างทำอะไรไม่ถูกเลยว่าฉันควรกรองความสัมพันธ์นี้อย่างไร (คุณสามารถเพิกเฉยต่อvalues_list()atm ได้)

ฟังก์ชันนี้แนบกับโปรไฟล์ผู้ใช้:

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.idไม่ใช่รายการ pks:

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

1
ดูเหมือนจะไม่ได้ผล เนื่องจาก self.role.id เป็นเพียง int เดียวและ trigger_roles เป็นรายการของพวกเขาฉันจึงต้องการการกลับด้านเช่นมี แต่อย่างที่ฉันค้นพบมีสำหรับสตริงเท่านั้น
Grave_Jumper

8
ตัวอย่างที่สองควรใช้งานได้ ถ้าค่าในการเป็นหนึ่งในบทบาทของทริกเกอร์แล้วว่าควรจะดึงตัวกรองขั้นตอนการทำงานทั้งหมดที่หนึ่งในบทบาทของทริกเกอร์เป็นค่าในself.role.id self.role.idโดยทั่วไปสิ่งนี้จะทำงานเหมือนกับฟังก์ชัน "มี" เว้นแต่ว่าเราทุกคนจะพลาดบางอย่างไป
Jordan Reiter

@Jordan Reiter: "มี" ถูกแปลงใน sql เป็น "like" ซึ่งไม่ใช่สิ่งที่ OP ต้องการและฉันคิดว่าเขาชี้ให้เห็นแล้วในทางกลับกัน "แน่นอน" จะถูกแปลงเป็น "=" หรือ "is" ซึ่งเป็น ความคิดที่นี่
mouad

@Grave_Jumper: ลองดูที่นี่ ( djangoproject.com/documentation/models/many_to_many ) คุณจะพบตัวอย่างเมื่อทำงานกับ ManytoMany Field หวังว่านี่จะช่วยคุณได้ถ้าคำตอบของฉันไม่ใช่ :)
mouad

1
ใช่ .. ขออภัยโซลูชันที่สองของคุณทำงานได้ดี :) มีการกำหนดค่าพลาดเล็กน้อยที่ด้านข้างของฉัน ขอบคุณที่ช่วยวันของฉัน ;-)
Grave_Jumper

19

วิธีที่ง่ายที่สุดในการบรรลุเป้าหมายนี้คือการตรวจสอบความเท่าเทียมกันในอินสแตนซ์ทั้งหมด (แทนที่จะเป็นรหัส) ในไฟล์ManyToManyField. ดูว่าอินสแตนซ์นั้นอยู่ในความสัมพันธ์แบบกลุ่มต่อกลุ่มมากหรือไม่ ตัวอย่าง:

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

7

ฉันรู้ว่านี่เป็นคำถามเก่า แต่ดูเหมือนว่า OP จะไม่ได้คำตอบที่เขาต้องการ ถ้าคุณมีสองชุดของ ManyToManyFields คุณต้องการเปรียบเทียบเคล็ดลับคือการใช้ผู้ประกอบการไม่ได้__in containsตัวอย่างเช่นหากคุณมีโมเดล "เหตุการณ์" ที่มี ManyToMany ถึง "กลุ่ม" ในฟิลด์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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.