1

我检查了许多 SO 文章,我不相信有任何方法可以完成我想做的事情,但在我放弃 Django 之前,我想阐明问题本身,看看我是否遗漏了什么。

我正在实现一个可以包含基本类型的子类的图(节点、边)。也就是说,一条边可以将基类连接到子类,或者将子类连接到子类,等等。. . 我希望能够拉出给定对象的所有边缘,找到这些边缘指向的对象,并在这些终端对象上调用一些函数。我希望我可以以多态的方式调用该函数,但我想不出一种方法来实现这一点。

class Node(models.Model):
    ...
    def dosomething():

class SpecialNode(Node):
    ...
    def dosomething():

class Edge(models.Model):
    #yes, related_name is weird, but this seems to be what makes sense
    source = models.ForeignKey(Node, related_name='targets')
    target = models.ForeignKey(Node, related_name='sources')

有了这个结构,我可以做到:

sourceedges = node.sources.all()
for sourceedge in sourceedges:
    sourceedge.source.dosomething()

但是“dosomething”函数总是在 Node 对象上调用,即使 source 实际上是一个 SpecialNode 对象。

我已经尝试使用 django_polymorphic 执行此操作,但我不相信这支持通过 Edge 对象进行 M2M 继承(由于我的应用程序中的其他原因,这是必需的)。

我尝试使用内容类型,但我认为每个类只允许一个通用关系。换句话说,Edge 中不能有 2 个不同的通用关系。

我想我可以建立一个名为 Endpoint 的对象,它上面只有一个通用关系,然后将 Edge 对象链接到它,如下所示:

class Endpoint(models.Model)
    ...
    content_object = generic.GenericForeignKey(...)

class Edge(models.Model)
    source = models.ForeignKey(Endpoint, related_name='targets')
    target = models.ForeignKey(Endpoint, related_name='sources')

但这在我的模型中引入了另一个级别的间接性,我开始觉得框架正在编码我而不是相反:)

无论如何,如果有人想出了完成这个特定用例的方法,请告诉我。欢迎使用比我上面建议的更好的方法,因为我目前喜欢使用 Django 开箱即用的很多东西。

谢谢

4

0 回答 0