【问题标题】:Making a tree structure in django models?在 django 模型中制作树结构?
【发布时间】:2013-03-18 20:41:11
【问题描述】:

我想要一个有 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(尤其是因为它在“空白”上给了我一个关键字错误)。有什么建议吗?

【问题讨论】:

  • 这些都很好,但是否可以像我在上面尝试的那样直接在字段中进行操作?我宁愿不要在其中包含另一个依赖项,而且在这种情况下我不太关心效率。
  • 为什么要使用ManyToOneRel?你只是在复制信息,parent 你可以使用关系向后找到它的孩子
  • 好吧,我想我有点关心效率。我想缓存给定父级的子级,因此我可以轻松地从模型实例中获取它们,而无需搜索整个数据库。

标签: python django activerecord django-models


【解决方案1】:

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

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

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

请注意,如果您打算用树做复杂的事情,您可能希望使用 django-mptt 库。

【讨论】:

    【解决方案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 类的实例。

    【讨论】:

      【解决方案3】:

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

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

      如您所见,没有blank 参数。

      【讨论】:

      • 对,我已经想通了。我想知道我应该改用什么。
      • 也许只是使用 CharField 来存储孩子的键和自定义方法或属性来根据请求实例化它们?
      猜你喜欢
      • 1970-01-01
      • 2019-12-18
      • 1970-01-01
      • 2012-01-07
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多