2016-09-15 3 views
1

신참 질문 : 장고 + 포스트 그레스 + PostGIS와장고 모델 조건 관계

내가 설정에 조건의 지오메트리 유형에 따라 기하 모델에 관련 될 필요가 장고의 사업 모델을 시도하고있다. 기하학 유형은 점, 선 또는 다각형입니다. 문제는 ========= 내가

같은 테이블 (따라서 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 right라는 동일한 필드에 다른 지오메트리 유형이 저장되는 것으로 가정합니다. 내 GIS 경험에서 나는 이것이 좋은 생각이 아니라는 것을 알고 있지만 어쨌든 중요하지 않습니다. 모든 단서? 그게 그렇게 중요한 건가? – skulk001

+0

예, 같은 기하 유형이 동일한 필드 유형에 저장되는 것은 중요하지 않습니다. – e4c5

+0

이것은 아주 좋습니다. 이 공간 쿼리의 결과에 어떤 의미를 가질 것인지 궁금 - 나는 다각형 내의 모든 프로젝트를 조회 찾고 말 - 나는 점 기하 구조가 컬렉션을 반환합니다 알고, 그 결과가 어떻게 보일지 라인과 폴리곤? Postgis는 교차를 수행하고 경계 다각형 내에있는 모든 지오메트리를 반환합니까? 당신이 __within에 대한 질문 또는 PostGIS와 쿼리를 __dwithin 경우 – skulk001

1

귀하의 Project 모델은 project_geometry 필드를 필요로하지 않는다. OneToOne 필드를 사용하여 다른 지오메트리 모델 만 프로젝트에 연결하면됩니다. 장고는 자동으로 ForeignKey, ManyToManyOneToOne 관계에 대한 역의 관계를 만듭니다. 귀하의 클래스는 다음과 같이 보일 것입니다 : 당신이 이런 식으로 역의 관계에 따라 다시 걸을 수있는 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() 

:

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

점 형상을 가진 모든 프로젝트를 쿼리를 사용하면 검색어 :

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

은 어떻게 프로젝트의 형상 유형을 알 수 있습니까? 내가 그 프로젝트의 기하학을 이해하기 위해 최악의 경우에 3 개의 쿼리를 필요로하지 않는 프로젝트 ID가 있다고 가정 해 보겠습니다. – skulk001

+0

역방향 관계가 없음인지 확인하여 쿼리 할 수 ​​있지만 대부분 예제를 단순화했습니다. – Soviut