在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
除了这些抽象概念之外,我还想构建更具体的概念:图形实际上是一个地图,一个节点可以是一条街道,一个房间在地图中有定义的坐标,边缘象征着两者之间的路径两个节点。在第二个cities
应用中,我基本上有:
from graphs.models import *
class Map(Graph):
# ...
class Element(Node):
# ...
class Path(Edge):
# ...
这就是继承的方式,以及我在Django模型关系中迷失自我的地方。
1 /我想丰富ForeignKey
和Element
之间的现有Map
以添加坐标(x,y),因为元素在空格中具有特定的位置一张地图。但我不确定这是可能的。我应该定义一个新关系(如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
找到它的元素?
或者我可能走错路,应该放弃这整个继承的想法?我非常喜欢它,因为它允许我将所有逻辑绑定到不同应用程序中的图形操作。
答案 0 :(得分:1)
这是我的方式,它可以真实地描述任何连接或断开的图形集合。只有你设置的问题才能阻止你连接不同图形中的两个节点,这应该是一个错误。
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')
你是对的,在这种情况下,忘记继承,这是一个非常错误的地方使用它。 此外,如果您想在实际地图上可视化图表,建议您使用Google地图和GeoDjango。但这是一个单独的主题:)