我检查了许多 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 开箱即用的很多东西。
谢谢