在django模型中制作树形结构?

时间:2013-03-18 20:41:11

标签: python django activerecord django-models

我想要一个包含2个字段的模型,包括子项和父项。我怎么在django做这个?我有类似的东西

from django.db import models
class FooModel(models.Model)
    parent = models.ForeignKey('self', blank=True, null=True)
    children = models.ManyToOneRel('self', blank=True, null=True)

    def __init__(self, *args, **kwargs):
        super(FooModel, self).__init__(*args, **kwargs)
        self.parent.children.add(self)

但是我不认为我应该像这样使用ManyToOneRel(特别是因为它在'blank'上给了我一个关键字错误)。有什么建议吗?

3 个答案:

答案 0 :(得分:19)

ManyToOneRel是一个内部实现类,它不适用于您的模型。

但是为什么你认为你还需要它呢?正如文档中详细解释的那样,当您定义ForeignKey时,您会自动获得反向关系。因此,在您的情况下,如果您定义parent,那么您已经自动获得self.foomodel_set:并且您可以使用related_name参数使其更加明确:

parent = models.ForeignKey('self', blank=True, null=True, related_name='children')

请注意,如果您计划使用树进行复杂的操作,则可能需要使用django-mptt库。

答案 1 :(得分:2)

class FooModel(models.Model)
    parent = models.ForeignKey('self', blank=True, null=True, related_name='children')


FooModel.objects.get(pk=1).children.all()

如果您希望缓存使用任何您想要的内容:在某处缓存查询,将父级中的所有子项存储为pks的平面列表,但不要忘记处理新实体以更新此列表。 ManyToOneRel用于django的内部需求,而且它不是Field类的实例。

答案 2 :(得分:0)

我找不到ManyToOneRel的文档,所以我查了code for it

def __init__(self, to, field_name, related_name=None, limit_choices_to=None,
        parent_link=False, on_delete=None):

如您所见,没有blank参数。