Django 模型条件关系
Django Model conditional relationship
新手问题:Django + Postgres + PostGIS
我正在尝试在 Django 中设置一个项目模型,该模型需要根据其几何类型有条件地与几何模型相关。几何类型是:点、线或多边形。问题是我如何在项目模型中定义这种关系,这样我就不必在同一个 table 中保存不同的几何类型(因此有 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
#几何模型
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()
您的 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)
其实你只需要一个模型。所有几何字段都派生自 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()
就是这样!一个模型,一个 table 而不是四个,这样更容易维护。并且由于去掉了关系字段,数据略小
新手问题:Django + Postgres + PostGIS
我正在尝试在 Django 中设置一个项目模型,该模型需要根据其几何类型有条件地与几何模型相关。几何类型是:点、线或多边形。问题是我如何在项目模型中定义这种关系,这样我就不必在同一个 table 中保存不同的几何类型(因此有 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
#几何模型
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()
您的 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)
其实你只需要一个模型。所有几何字段都派生自 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()
就是这样!一个模型,一个 table 而不是四个,这样更容易维护。并且由于去掉了关系字段,数据略小