2013-02-09 27 views
5

Tôi đang cố gắng lập mô hình dữ liệu được tổ chức dưới dạng cây phân cấp bằng bảng đóng. Các mục sẽ đại diện cho các nút trong cây là không có gì ưa thích và được định nghĩa như sau.Bàn và Bảng đóng cửa Django

class Region(models.Model): 
    RegionGuid = models.CharField(max_length=40, unique=True, db_column='RegionGUID', blank=True) 
    CustomerId = models.IntegerField(null=True, db_column='CustomerID', blank=True) 
    RegionName = models.CharField(max_length=256, db_column='RegionName', blank=True) 
    Description = models.TextField(db_column="Description", blank=True) 
    class Meta: 
     db_table = u'Region' 

Đường dẫn giữa các nút được xác định bằng bảng đóng sau. Nó bao gồm một FK đến nút tổ tiên, FK đến nút hậu duệ và chiều dài đường dẫn (số ví dụ của các nút) giữa tổ tiên và Hậu duệ:

class RegionPath(models.Model): 
    Ancestor = models.ForeignKey(Region, null=True, db_column='Ancestor', blank=True) 
    Descendant = models.ForeignKey(Region, null=True, db_column='Descendant', blank=True) 
    PathLength = models.IntegerField(null=True, db_column='PathLength', blank=True) 
    class Meta: 
     db_table = u'RegionPath' 

Bây giờ làm thế nào tôi sẽ lấy lại tất cả Region hàng và nút cha của mình (tức là nơi RegionPath.PathLength = 1)? SQL của tôi là hơi gỉ nhưng tôi nghĩ rằng các truy vấn SQL nên tìm một cái gì đó như thế này.

SELECT r.* from Region as r 
LEFT JOIN 
(SELECT r2.RegionName, p.Ancestor, p.Descendant from Region as r2 INNER JOIN RegionPath as p on r2.id = p.Ancestor WHERE p.PathLength = 1) AS Parent 
on r.id = Parent.Descendant 

Bất kỳ trợ giúp nào trong việc diễn đạt điều này bằng cách sử dụng API truy vấn của Django sẽ được đánh giá cao.

+0

không chắc chắn nếu có nhiều trợ giúp vì nó là một ngôn ngữ khác (php/codeigniter) nhưng tôi đã có một vở kịch với việc thực hiện các bảng đóng, và có lẽ nó sẽ cung cấp cho bạn một số ý tưởng. https://gist.github.com/dazld/2174233 – dmp

+0

Cảm ơn bạn đã liên kết nhưng tôi không nghĩ điều đó sẽ giúp ích cho tôi. Tôi có thể làm việc ra logic của truy vấn và tôi có thể viết truy vấn nếu trong SQL thô nếu cần thiết. Tôi chỉ bị bối rối bởi API truy vấn Django. – CadentOrange

+0

Có lý do cụ thể nào bạn cần sử dụng các bảng đóng cửa tại đây không? Có một thực hiện Django rất tốt đẹp của [MPTT] (https://github.com/django-mptt/django-mptt), ví dụ, mà giải quyết cùng một vấn đề. –

Trả lời

1

Bằng cách thêm related_name cho các phím nước ngoài như vậy:

class RegionPath(models.Model): 
    Ancestor = models.ForeignKey(Region, null=True, db_column='Ancestor', blank=True, related_name="ancestor") 
    Descendant = models.ForeignKey(Region, null=True, db_column='Descendant', blank=True, related_name="descendants") 
    PathLength = models.IntegerField(null=True, db_column='PathLength', blank=True) 
    class Meta: 
     db_table = u'RegionPath' 

Bạn có thể thực hiện truy vấn cho một trong hai mối quan hệ:

children = Region.objects.filter(ancestors__PathLength=1) 
parents = Region.objects.filter(descendants__PathLength=1) 

tôi đã thực hiện thử nghiệm của tôi trên một mô hình rất giống nhau. Bạn có thể phải thêm .distinct(), bạn có thể muốn select_related() để giảm truy vấn.