2016-09-15 10 views
1

初心者の質問:ジャンゴ+の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

実際には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() 

これがすべてです! 1つのモデル、4つではなく1つのテーブルで、保守がはるかに簡単です。また、関係フィールドが削除されているため、データはわずかに小さくなります。その場なし

+0

これは、異なるジオメトリタイプがproject_geometry rightという同じフィールドに保存されることを前提としています。私のGISの経験から、これは良い考えではないことは分かっていますが、多分問題ではありません。すべての手がかりは?それは問題ですか? – skulk001

+0

ええ、異なったジオメトリが同じフィールドタイプに保存されても問題ありません。 – e4c5

+0

これは素晴らしいことです。これは、空間クエリの結果上の任意の意味を持っているかどう疑問に思う - 私は、ポリゴン内のすべてのプロジェクトを照会しているよと言う - 私はポイントのgeomがコレクションを返します知っている、その結果は次のようになりますどのようにラインとポリゴンのために? postgisは交差を実行し、境界ポリゴン内のすべてのジオメトリを返しますか? – skulk001

1

あなたProjectモデルはproject_geometryフィールドを必要としません。 OneToOneフィールドを使用して、異なるジオメトリモデルをプロジェクトに関連付けるだけです。 Djangoは自動的にForeignKeyManyToManyOneToOne関係を逆の関係を作成します。点ジオメトリを持つすべてのプロジェクトのためにあなたを照会するには

project = Project.objects.get(id=1) 
point = project.point_geo.point 

:あなたはこのような逆の関係に沿って戻って歩くことができるProjectインスタンスを持っている場合は

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

:あなたのクラスは次のようになりますクエリ可能:

projects_with_points = Project.objects.exclude(point_geo=None) 
+0

は、どのように私は、プロジェクトのジオメトリタイプを知っているのだろうか?私はプロジェクトのIDを持っていると言いますが、最悪の場合にそのジオメトリを理解するために3つのクエリを必要としませんか? – skulk001

+0

リバースリレーションシップのいずれかがnoneであるかどうかをチェックすることで問合せを行うことができますが、ほとんど例を単純化しています。 – Soviut

関連する問題