django出现ValueError("Empty point is not representable in WKB.")的解决方案
报错的原因
这个错误通常是由于在Django的数据模型中定义了一个空的点字段(PointField),并试图将其保存到数据库中。由于空点不能在WKB(二进制Well-Known Text)格式中表示,因此Django会引发这个错误。
可以考虑使用null=True或blank=True,
或者在给point字段默认值,使得它不为空。
例如:
point = models.PointField(default="POINT(0 0)")
还有一种情况是在创建模型实例时,将PointField设置为None或空值。 这将导致上述错误。 要避免这种情况,可以在创建模型实例时提供非空的点值。
例如:
mymodel = MyModel(point=Point(x=1, y=1))
mymodel.save()
同样在更新的时候也要注意这个问题
MyModel.objects.filter(id=1).update(point=Point(x=1, y=1))
在使用Django的空间查询时,可能也会出现此错误,例如在使用Q()对象查询时将空值传递给点字段。
总之,此错误通常是由于在Django模型中使用了空点而导致的。 要解决此错误,可以遵循上述建议。
如何解决
解决方案有以下几种:
1. 使用null=True或blank=True参数为PointField字段指定可空值
2. 在创建模型实例时传入非空的点值,不要传入空值或None
3. 在给point字段默认值,使得它不为空。
如果你在使用Django的空间查询时出现这个问题,请检查你的查询条件是否传递了空值给点字段。
一些具体示例:
class MyModel(models.Model):
point = models.PointField(blank=True, null=True)
#or
point = models.PointField(default="POINT(0 0)")
MyModel.objects.create(point=Point(1,1))
MyModel.objects.filter(point__isnull=False)
这些修改应该能解决 ValueError: Empty point is not representable in WKB. 的问题。
此外,在使用Django的空间数据库存储时,需要确保数据库引擎支持WKB格式。
例如,如果使用MySQL数据库,则需要安装MySQL的GIS插件,并在数据库中创建空间索引。
另外如果你使用的是Django version <3.1, 你需要安装django.contrib.gis 并在settings文件中加上
INSTALLED_APPS = [
...
'django.contrib.gis',
]
当然了如果你使用的是Django version >=3.1, GIS会自带在INSTALLED_APPS里面。
如果你还是遇到问题, 你需要检查你的数据库配置是否正确, 数据库服务器是否开启,空间扩展是否已经安装。
总之就是确保Django和数据库有正确的配置和空间扩展支持。
使用例子
这是一个在Django中使用PointField并使用MySQL数据库的示例:
# settings.py
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.mysql',
'NAME': 'mydatabase',
'USER': 'myuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
'PORT': '3306',
'OPTIONS': {
'charset': 'utf8mb4',
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"
},
}
}
#models.py
from django.contrib.gis.db import models
class Place(models.Model):
name = models.CharField(max_length=255)
location = models.PointField()
objects = models.Manager()
# migration
./manage.py makemigrations
./manage.py sqlmigrate # check SQL query
./manage.py migrate
以上是一个简单的模型定义。这个模型有一个名为“Place”的类和一个名为“location”的PointField。
在这里,我们使用MySQL数据库作为Django默认数据库引擎。要注意的是,在此示例中,我们使用了django.contrib.gis.db.backends.mysql作为数据库引擎,并在settings.py文件中设置了DATABASES字典。
这些更改应该能够解决ValueError: Empty point is not representable in WKB.的问题。