深度关系搜索

发布于 2024-10-24 20:28:41 字数 651 浏览 5 评论 0原文

我正在寻找解决此问题的“pythonic”/“orm-ic”解决方案...

模型 Soldier 本身有一个 ManyToManyField。

class Soldier(models.Model):
    ...
    subordinates = models.ManyToManyField('Soldier', ...)

ABCSoldier 对象,

它们形成一种“命令链”,如下所示: A > ; B> C

B 位于 A.subscribeds.all()
C 位于 B.sublineds.all()

获取 A 的所有下属的最佳方法是什么?
类似 A.get_all_subscribeds() 的内容,应该返回 [B, C]

我们不知道运行时这种关系有多少层。 (C 可以有一些自己的下属,B 可以有兄弟姐妹,等等)

I am looking for a "pythonic" / "orm-ic" solution for this problem...

Model Soldier has a ManyToManyField to itself.

class Soldier(models.Model):
    ...
    subordinates = models.ManyToManyField('Soldier', ...)

A, B and C are Soldier objects

They form kind of "chain of command" like so: A > B > C

B is in A.subordinates.all()
C is in B.subordinates.all()

What's the best way to get all subordinates of A?
Something like A.get_all_subordinates(), that should return [B, C].

We don't know how many levels of this relation there is at runtime. (C can have some subordinates of his own, B can have siblings, etc.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

〃温暖了心ぐ 2024-10-31 20:28:41

如果你的模型是上级的<->从属关系与多对多关系,您最终会得到一个类似图形的结构,可以得到任意复杂的(例如循环关系)。这将变得很难有效地查询。

如果您想要树状结构(这意味着每个士兵最多有一个直接上级),您可以使用django-mptt

from django.db import models
from mptt.models import MPTTModel

class Soldier(MPTTModel):
    parent = models.ForeignKey('self', null=True, blank=True)

获取所有下级就像这样简单

subordinates = soldier.get_descendants()

get_descendants 最好的事情是:它只导致一个查询得到所有的后代。

If you model the superior <-> subordinate relation with a many-to-many relation, you'll end up with a graph-like structure that can get arbitrary complex (e.g. circular relations). This will become very hard to query efficiently.

If you're after a tree-like structure (which means that every Soldier has at most one direct superior), you could use django-mptt:

from django.db import models
from mptt.models import MPTTModel

class Soldier(MPTTModel):
    parent = models.ForeignKey('self', null=True, blank=True)

Getting all the subordinates is then as easy as

subordinates = soldier.get_descendants()

And the best thing about get_descendants: it causes exactly one query to get all descendants.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文