【问题标题】:Modelling a 'web' in a Django database在 Django 数据库中建模“网络”
【发布时间】:2019-07-26 10:59:06
【问题描述】:

我有一个用例,我有一个具有以下关系的“网络”;在 Django 中对此进行建模的最佳方法是什么?

  1. 有一个逻辑顶层(如果需要,可以建模为单个“非常顶层”节点)
  2. 底部有逻辑叶子
  3. 节点可以与上层和/或下层中的节点建立关系,但不能与兄弟节点建立关系

就像那个中国游戏一样,硬币从针脚下掉下来,从上到下有多条路线,但遍历总是有效的,尽管在其他地方以某种方式确定(在我的情况下实际上是用户输入)。

我尝试过使用多对多关系,但不知道如何找出关系的顶部和底部;我是否需要切换到多个 OneToMany 关系以获得独立的子关系和父关系?

【问题讨论】:

    标签: django database


    【解决方案1】:

    我认为您不能在数据结构中明确表示这种图形,但您可以在节点的创建/更新中通过语义操作来实现它。假设您有一个节点模型:

    class Node(models.Model):
        connections = ManyToManyField(Node)
        layer_level = IntegerField(null=False, default=1)
    

    在构造函数和魔法设置器__setattr__ 中,您可以检查节点的连接是否都具有大于或小于节点本身的层级,如果它们相等则引发异常。我承认在 Django “插入”中,模型实例的字段设置可能比覆盖 __setattr__ 方法更复杂,但这超出了此答案的范围。

    关键是您可以建立一个具有所需结构但限制较少的模型,然后强制执行创建/更新的限制,而不是将它们隐含在模型结构中。后者将是一个更好的解决方案,但也是关系数据库和/或 Django 的 ORM 可能无法实现的解决方案。

    【讨论】:

    • 艾蒂安,感谢您的响应和层级。暂时忽略了这一点,我在代码中发现了一个错误,在该错误中我从两个方向添加关系并修复了该问题,一切正常。我所做的是: 1. 创建从对象类型 X 到 X 的多对多关系,称为 parents 2. 使用 related_name 选项以相反方向创建 children。 3. 永远做child_object.add(parents),永远不要反其道而行之。现在顶部可以通过 `..filter(parents__id__isnull=True) 来识别,底部的孩子也是如此。
    猜你喜欢
    • 1970-01-01
    • 2016-09-27
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多