5

Я пытаюсь моделировать данные, которые организованы как иерархическое дерево, используя таблицу закрытия. Записи, которые будут представлять узлы в дереве, ничем не отличаются и определяются следующим образом.Таблицы ORM и закрытия 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' 

Пути между узлами определяются с использованием следующей таблицы замыкания. Она состоит из FK к узлу предка, FK к узлу потомка и длине пути (т.е. число узлов) между предком и потомком:

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' 

Теперь как бы я получить все Region строк и их соответствующий родительский узел (т.е. где RegionPath.PathLength = 1)? Мой SQL немного ржавый, но я думаю, что SQL-запрос должен выглядеть примерно так.

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 

Любая помощь в выражении этого с использованием API QuerySet Django была бы высоко оценена.

+0

Не уверен, что помощь, так как это другой язык (php/codeigniter), но у меня была игра с реализацией закрывающих таблиц, и, возможно, это даст вам некоторые идеи. https://gist.github.com/dazld/2174233 – dmp

+0

Спасибо за ссылку, но я не думаю, что это помогает мне. Я могу разработать логику запроса, и я могу написать запрос, если в необработанном SQL при необходимости. Я просто запутался в API Django QuerySet. – CadentOrange

+0

Есть ли какая-то конкретная причина, по которой вам нужно использовать таблицы закрытия? Например, очень хорошая реализация Django [MPTT] (https://github.com/django-mptt/django-mptt), которая решает ту же проблему. –

ответ

1

Добавляя related_name для внешних ключей, как так:

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' 

Вы можете делать запросы для любого соотношения:

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

я сделал тест на очень похожей модели. Возможно, вам придется добавить .distinct(), вы можете захотеть select_related() для уменьшения запросов.

 Смежные вопросы

  • Нет связанных вопросов^_^