0

私は次のモデルを持っています (とりわけ)、クロージャーテーブルを使用してツリー構造を補完しようとしています:

class Part(models.Model):
    name = models.TextField()
    quantity = models.IntegerField()

    manufacturer = models.ForeignKey(Manufacturer)

    def __str__(self):
        return "Part {}: {}, {}".format(self.id, self.name, self.quantity)

    def path(self):
        ancestors = Part.objects.filter(closures_d__descendant__id__exact=self.id)
        print(len(ancestors))
        return "{}".format(reduce(lambda a, b: a+" > "+b, map(lambda x: x.name, ancestors), ""))

    class Meta:
        db_table = 'parts'

class Closure(models.Model):

    ancestor = models.ForeignKey(Part, related_name='closures_a')
    descendant = models.ForeignKey(Part, related_name='closures_d')

    class Meta:
        db_table = 'closures'

問題は、path関数が期待どおりに機能しないことです。データベースから先祖をフェッチするクエリは、1 つのオブジェクト (それを呼び出した部分) のみを返します。生成された SQL クエリを確認したところ、クロージャが無視されているようです (connection.queries からの出力):

[{'time': '0.001', 'sql': 'SELECT "parts"."id", "parts"."name", "parts"."quantity", "parts"."manufacturer_id" FROM "parts" WHERE "parts"."id" = 101 '}]

結合を正しく行うには?(つまり、Python/Django の方法で、生の SQL でこれを行うことができます)

クエリは次のようになります (101 は ID の例、一部はデータベースに存在し、先祖はほとんどありません。以下のクエリは正しい結果を返します)。

SELECT * from parts p JOIN closures c ON p.id=c.ancestor_id WHERE c.descendant_id=101
4

1 に答える 1