新手问题:Django + Postgres + PostGIS
我正在尝试在Django中设置一个Projects模型,该模型需要根据几何类型与几何模型有条件地相关。几何类型包括:点,线或多边形。问题是如何在项目模型中定义这种关系,这样我就不必在同一个表中保存不同的几何类型(因此有3种不同的几何模型)
=======================这是我的模特==================== ======
PRJ_GEOM = (
(1, "point"),
(2, "line"),
(3, "polygon")
)
class Project(models.Model):
name = models.CharField(max_length=20)
project_geom_type = models.IntegerField(choices=PRJ_GEOM)
project_geometry = models.OneToOneField( ????) # I am stuck here - how do I express this conditional relationship which depends on project_geom_type
#Geometry Model
class Project_Point_Geom(models.Model):
project = models.OneToOne(Project, on_delete=models.CASCADE, related_name='project_point')
point = models.PointField()
class Project_Line_Geom(models.Model):
project = models.OneToOne(Project, on_delete=models.CASCADE, related_name='project_line')
line = models.LineStringField()
class Project_Polygon_Geom(models.Model):
project = models.OneToOne(Project, on_delete=models.CASCADE, related_name='project_polygon')
polygon = models.PolygonField()
答案 0 :(得分:1)
您的Project
模型不需要project_geometry
字段。您只需使用OneToOne
字段将不同的几何模型与项目相关联。 Django自动为ForeignKey
,ManyToMany
和OneToOne
关系创建反向关系。你的课程看起来像这样:
class Project(models.Model):
name = models.CharField(max_length=20)
class Point_Geo(models.Model):
project = models.OneToOne(Project) # truncated for example
point = models.PointField()
class Line_Geo(models.Model):
project = models.OneToOne(Project) # truncated for example
line = models.LineStringField()
class Polygon_Geo(models.Model):
project = models.OneToOne(Project) # truncated for example
polygon = models.PolygonField()
当你有Project
个实例时,你可以沿着这样的反向关系走回去:
project = Project.objects.get(id=1)
point = project.point_geo.point
要查询具有点几何的所有项目,您可以查询:
projects_with_points = Project.objects.exclude(point_geo=None)
答案 1 :(得分:1)
实际上你只需要一个型号。所有几何字段都派生自GeometryField,因此您可以使用它来存储它的子类。
PRJ_GEOM = (
(1, "point"),
(2, "line"),
(3, "polygon")
)
class Project(models.Model):
name = models.CharField(max_length=20)
project_geom_type = models.IntegerField(choices=PRJ_GEOM)
project_geometry = models.GeometryField()
就是这样!一个模型,一个表而不是四个,更容易维护。并且数据略小,因为关系字段被消除了。