Django Model条件关系

时间:2016-09-15 23:23:41

标签: django django-models postgis geodjango

新手问题: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()

2 个答案:

答案 0 :(得分:1)

您的Project模型不需要project_geometry字段。您只需使用OneToOne字段将不同的几何模型与项目相关联。 Django自动为ForeignKeyManyToManyOneToOne关系创建反向关系。你的课程看起来像这样:

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()

就是这样!一个模型,一个表而不是四个,更容易维护。并且数据略小,因为关系字段被消除了。