Django 如何使地理领域独一无二?

Django 如何使地理领域独一无二?,django,gis,postgis,geodjango,django-postgresql,Django,Gis,Postgis,Geodjango,Django Postgresql,我有这个模型: class Marker(models.Model): location = models.PointField(geography=True, unique=True) 当我试图通过管理界面添加标记实例时,它会引发一个ValueError: File "django/core/handlers/base.py" in get_response 111. response = callback(request, *callback_args, **callback_

我有这个模型:

class Marker(models.Model):
    location = models.PointField(geography=True, unique=True)
当我试图通过管理界面添加标记实例时,它会引发一个
ValueError

File "django/core/handlers/base.py" in get_response
  111. response = callback(request, *callback_args, **callback_kwargs)
File "django/contrib/admin/options.py" in wrapper
  366. return self.admin_site.admin_view(view)(*args, **kwargs)
File "django/utils/decorators.py" in _wrapped_view
  91. response = view_func(request, *args, **kwargs)
File "django/views/decorators/cache.py" in _wrapped_view_func
  89. response = view_func(request, *args, **kwargs)
File "django/contrib/admin/sites.py" in inner
  196. return view(request, *args, **kwargs)
File "django/utils/decorators.py" in _wrapper
  25. return bound_func(*args, **kwargs)
File "django/utils/decorators.py" in _wrapped_view
  91. response = view_func(request, *args, **kwargs)
File "django/utils/decorators.py" in bound_func
  21. return func(self, *args2, **kwargs2)
File "django/db/transaction.py" in inner
  209. return func(*args, **kwargs)
File "django/contrib/admin/options.py" in add_view
  937. if form.is_valid():
File "django/forms/forms.py" in is_valid
  124. return self.is_bound and not bool(self.errors)
File "django/forms/forms.py" in _get_errors
  115. self.full_clean()
File "django/forms/forms.py" in full_clean
  272. self._post_clean()
File "django/forms/models.py" in _post_clean
  338. self.validate_unique()
File "django/forms/models.py" in validate_unique
  347. self.instance.validate_unique(exclude=exclude)
File "django/db/models/base.py" in validate_unique
  633. errors = self._perform_unique_checks(unique_checks)
File "django/db/models/base.py" in _perform_unique_checks
  724. if qs.exists():
File "django/db/models/query.py" in exists
  565. return self.query.has_results(using=self.db)
File "django/db/models/sql/query.py" in has_results
  441. return bool(compiler.execute_sql(SINGLE))
File "django/db/models/sql/compiler.py" in execute_sql
  808. sql, params = self.as_sql()
File "django/db/models/sql/compiler.py" in as_sql
  82. where, w_params = self.query.where.as_sql(qn=qn, connection=self.connection)
File "django/db/models/sql/where.py" in as_sql
  91. sql, params = child.as_sql(qn=qn, connection=connection)
File "django/db/models/sql/where.py" in as_sql
  94. sql, params = self.make_atom(child, qn, connection)
File "django/contrib/gis/db/models/sql/where.py" in make_atom
  47. spatial_sql = connection.ops.spatial_lookup_sql(data, lookup_type, params_or_value, lvalue.field, qn)
File "django/contrib/gis/db/backends/postgis/operations.py" in spatial_lookup_sql
  497. '"%s" lookup.' % lookup_type)

Exception Type: ValueError at /admin/coremap/marker/add/
Exception Value: PostGIS geography does not support the "exact" lookup.
根据,一个
geography
类型实际上没有
精确的
字段查找。有没有办法不使用
精确的
来完成
唯一的
约束

我正在使用:

  • Postgresql 9.1
  • PostGIS 1.5
  • Django 1.4.3

我不知道是否可以在Django中直接执行此操作,或者是否需要在事后添加索引,但PostgreSQL确实支持唯一的函数索引

可以使用以下方法强制执行唯一的几何图形:

CREATE UNIQUE INDEX tbl_geometry_idx_u ON mytable(geometry_to_text(mygeom));

这将在几何图形列的文本表示上创建唯一索引。大小可能有限制(我不希望索引对烤面包值很有效),但如果几何体字段中有那么多点,那么在唯一约束方面就会有其他问题。

我遇到了类似的问题,但使用了较新版本的Django(1.10.5)、PostGIS(2.0)和Postgres(9.4)(Op的问题离这个答案还有4年)

Django向我提出的错误有点不同,但与此相关:


ValueError:PostGIS地理不支持“~=”函数/运算符。

事实证明,在这个版本中,Django PostGIS后端使用“~=”操作符来验证某个记录是否已经存在,但PostGIS在地理类型上不支持这一点。不确定GeoDjango开发人员为什么没有使用“=”操作符,而地理类型和几何类型都支持该操作符

因此,我找到的解决方案是通过在models.py文件的顶部添加monkey补丁来对Django PostGIS后端进行修补(也许有更优雅的方法来进行修补),但对我来说效果很好

from django.contrib.gis.db.backends.postgis.operations import (PostGISOperator,
                                                               PostGISOperations,
                                                               BILATERAL)
PostGISOperations.gis_operators['exact'] = PostGISOperator(op='=', 
                                                           geography=True, 
                                                           raster=BILATERAL)
PostGISOperations.gis_operators['same_as'] = PostGISOperator(op='=', 
                                                             geography=True, 
                                                             raster=BILATERAL)
我想,如果您仍然在项目中使用较旧版本的Django和PostGIS,您可能需要验证给定的运算符是否受支持,以及在该特定版本的Django中如何处理后端运算符。

恭喜:)在我看来,这是一个bug-您应该在VM中测试重新安装,以再次检查它是否不是安装。