2016-09-15 72 views
1

新手問題:Django的+ Postgres的+ PostGIS的Django的模型中條件關係

我試圖建立在Django一個項目的模型,需要有條件地與根據其幾何類型幾何模型。幾何類型是:點,線或多邊形。問題是如何在項目模型中定義這種關係,以便我不必在同一個表中保存不同的幾何類型(因此,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() 

回答

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

就這樣!一個模型,一個桌子而不是四個,這更容易維護。由於關係字段被消除,數據略小。

+0

我假設這將導致不同的幾何類型被保存在名爲project_geometry的相同字段中。從我的GIS經驗中我知道這不是一個好主意,但也許並不重要。任何線索?有關係嗎? – skulk001

+0

是的,不同的幾何圖形保存在相同的字段類型中並不重要。 – e4c5

+0

這太好了。想知道這是否會對空間查詢的結果產生任何影響 - 比如我正在查詢多邊形中的所有項目 - 我知道點geoms將返回一個集合,對於線條和多邊形,結果將如何? postgis是否執行交點並返回邊界多邊形內的所有幾何? – skulk001

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) 
+0

沒有該字段我將如何知道項目的幾何類型?假設我有一個項目Id,在最壞的情況下我不需要3個查詢來找出它的幾何形狀? – skulk001

+0

您可以通過檢查是否有任何反向關係是無查詢來進行查詢,但我大多隻是簡化了示例。 – Soviut