在 Django 项目中,我想基本上代表一个城市环境:一些建筑物和街道,并且可以在它们之间移动。为了实现这一目标,我选择了 graph表示:每个节点代表一个房间或一条路,每个边代表在两个节点之间行驶的可能性。
所以我有第一个应用程序graphs
,具有以下Graph
、Node
和Edge
模型:
class Graph(models.Model):
label = models.CharField(max_length=200)
class Node(models.Model):
graph = models.ForeignKey(Graph)
# some methods
class Edge(models.Model):
node_a = models.ForeignKey(Node, related_name='node_a')
node_b = models.ForeignKey(Node, related_name='node_b')
# some methods
除了这些抽象概念之外,我想构建更具体的概念:图表实际上是一张 map ,节点可以是 map 中定义坐标的街道或房间,边象征着之间的路径两个节点。在第二个cities
应用程序中,我基本上有:
from graphs.models import *
class Map(Graph):
# ...
class Element(Node):
# ...
class Path(Edge):
# ...
这就是继承的障碍,也是我在 Django 模型关系中迷失的地方。
1/我想丰富 Element
和 Map
之间现有的 ForeignKey
以添加坐标 (x, y),因为元素在 map 空间中具有特定位置。但我不确定这是否可能。我应该定义一个新关系(如 it's been done here )吗?就建筑而言,这不是很糟糕吗?如果这是要做的事情,我如何向这种关系添加额外的数据(即坐标)? (我知道 m2m-through ,我不需要 m2m 关系,这正是我这里需要的)。
2/通过继承,Element
(即 Node
)属于 Map
(即 Graph
),但显然我不能这样做:
>>> map = Map.objects.get(id=1) # suppose it exists and has a few Elements
>>> map_elements = map.element_set().all()
AttributeError: 'Map' object has no attribute 'element_set'
有没有办法告诉 Django 使用 Map
的父 node_set
来查找其元素?
或者也许我走错了路,应该放弃整个继承的想法?我非常喜欢它,因为它允许我将所有与图形操作绑定(bind)的逻辑保留在不同的应用程序中。
最佳答案
这是我的做法,它可以真实地描述任何连接或断开连接的图的集合。该设置遇到的唯一问题是没有什么可以阻止您连接来自不同图表的两个节点,这应该是一个错误。
class Graph(models.Model):
label = models.CharField(max_length=200)
class Node(models.Model):
graph = models.ForeignKey(Graph)
x = models.IntegerField()
y = models.IntegerField()
neighbors = models.ManyToMayField('self')
您不需要实际的边缘模型,除非您还想描述有向图。在这种情况下,它将是:
class Graph(models.Model):
label = models.CharField(max_length=200)
class Node(models.Model):
graph = models.ForeignKey(Graph)
x = models.IntegerField()
y = models.IntegerField()
class Edge(models.Model):
start = models.ForeignKey(Node, related_name='start_node_set')
end = models.ForeignKey(Node, related_name='end_node_set')
你是对的,在这种情况下,忘记继承,这是一个非常错误的使用它的地方。 另外,如果您想在实际 map 上可视化图形,建议使用 Google map 和 GeoDjango。但这是一个单独的主题:)
关于python - 从 child 模型中了解 parent 的关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25571074/