2011-02-15 30 views
7

Những người thân yêu đang cố gắng giúp đỡ người khác,Cách Django ORM trải qua nhiều mối quan hệ Nhiều-Nhiều-Nhiều

Tôi đang cố gắng tìm cách để Django tham gia với tôi mà không cần viết SQL tùy chỉnh.

Hãy nói rằng tôi có các mô hình sau

class Parent(models.Model): 
    name = models.CharField() 
    children = models.ManyToManyField(Child, through="Parent_Child", related_name="parents") 

class Parent_Child(models.Model): 
    parent = models.ForeignKey(Parent, related_name='attached_children') 
    child = models.ForeignKey(Child, related_name='attached_parents') 

class Child(models.Model): 
    name = models.CharField() 
    toys = models.ManyToManyField(Toy, hrough="Child_Toy", related_name="toy_owners") 

class Child_Toy(models.Model): 
    child = models.ForeignKey(Child, related_name='attached_toys') 
    toy = models.ForeignKey(Toy, related_name='toy_owner') 

class Toy(models.Model): 
    name = models.CharField 

Một phụ huynh có thể có nhiều trẻ em. Một đứa trẻ có thể có nhiều cha mẹ. Một đứa trẻ có thể sở hữu nhiều đồ chơi. Đồ chơi có thể được sở hữu bởi nhiều trẻ em.

Tôi muốn nhận danh sách tất cả đồ chơi thuộc sở hữu của Cha mẹ.

Vì vậy, tôi có thể làm những việc như: parent.children.all()child.toys.all()

những gì tôi muốn làm là một cái gì đó giống như parent.children.toys.all() Khi tôi cố gắng để làm điều này tôi nhận được: AttributeError: 'ManyRelatedManager' object has no attribute 'toys'. Tôi hiểu lỗi - parent.children trả về nhiều bản ghi. Điều này được mong đợi. Những gì tôi không thể tìm ra là làm thế nào để cung cấp cho Django gợi ý rằng tôi muốn nó để thêm một tham gia bổ sung để truy vấn của nó.

Có cách nào tôi có thể làm điều này tham gia trong Django hay tôi cần phải đi đến SQL tùy chỉnh để làm điều này?

Xin lưu ý: Ở trên chỉ nhằm minh họa vấn đề của tôi, các mô hình thực tế mà tôi đang sử dụng không phù hợp. Vấn đề của tôi là thực sự cố gắng tìm ra cách để tham gia thông qua nhiều mối quan hệ M2M ở Django mà không cần phải sử dụng SQL.

Tôi đánh giá cao sự trợ giúp của bạn trước. Cảm ơn!

+2

Tôi không muốn viết một câu trả lời mới, nhưng sẽ thêm một liên kết đến tài liệu: http : //docs.djangoproject.com/en/dev/topics/db/queries/#lookups-that-span-relationships để biết thông tin về django JOINs cụ thể sẽ hữu ích khi tìm hiểu cách bộ lọc chuỗi() ảnh hưởng đến truy vấn m2m của bạn –

Trả lời

7

Đơn giản chỉ cần viết một cái gì đó như:

Toy.objects.filter(toy_owners__parents=parent) 
+0

những gì _owners và __parents có nghĩa là gì? –

2

Nếu bạn không lưu trữ thông tin bổ sung trong bảng trung gian Parent_ChildChild_Toy bạn chỉ có thể rời chúng ra - Django sẽ tạo ra một cách tự động cho bạn. Vì vậy, một thiết lập đơn giản sẽ trông như thế này:

class Parent(models.Model): 
    name = models.CharField(max_length=80) 
    children = models.ManyToManyField('Child', related_name="parent") 

class Child(models.Model): 
    name = models.CharField(max_length=80) 
    toys = models.ManyToManyField('Toy', related_name="owner") 

class Toy(models.Model): 
    name = models.CharField(max_length=80) 

Bạn có thể truy vấn các đồ chơi cho cha mẹ cụ thể bằng cách sử dụng field lookups.

Toy.objects.filter(owner__parent__id=1) 

Hoặc:

Toy.objects.filter(owner__parent=parent) 

Các resulting SQL trông giống như sau:

SELECT "toy"."id", "toy"."name" FROM "toy" 
    INNER JOIN "child_toys" 
     ON ("toy"."id" = "child_toys"."toy_id") 
    INNER JOIN "child" 
     ON ("child_toys"."child_id" = "child"."id") 
    INNER JOIN "parent_children" 
     ON ("child"."id" = "parent_children"."child_id") 
    WHERE "parent_children"."parent_id" = 1 
Các vấn đề liên quan