微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

geography = True的Django PointField无法保存数据:SQL函数错误

如何解决geography = True的Django PointField无法保存数据:SQL函数错误

我有一个安装了GIS扩展名的Django 3.1.2Postgresql 12PostGIS 3

在我的模型中,我尝试将PointFieldgeography=True一起使用来存储实际坐标:

location = models.PointField(geography=True,srid=4326,blank=False,null=False,verbose_name=_("Lat/Lon coordinates"))

在管理菜单中,我正在使用OSMWidget输入坐标:

location = forms.PointField(widget=forms.OSMWidget(attrs={'map_width': 800,'map_height': 500,'default_zoom': 15}))

保存后,Django会遇到以下sql错误

INSERT INTO "challenges_point" ("track_id","sortkey","name","location") VALUES (15,10,'Start',ST_Transform(ST_GeogFromWKB('\x...'::bytea),4326)) RETURNING "challenges_point"."id";
ERROR:  function st_transform(geography,integer) does not exist
LINE 1: ...",ST_Transfo...
                                                   ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

ST_Transform()用于变换几何点(如果geography=False用于PointField,则用作数据类型)。但是我不确定要使其与地理环境一起工作需要什么。

解决方法

由于您覆盖了PointField,所以它没有设置纬线设置,并且使用ST_Transform将geom转换为正确的空间参考。

有几种方法可以正确更改窗口小部件,但是我将用当前代码为您提供最简单的窗口小部件:

location = forms.PointField(
    srid=4326,widget=forms.OSMWidget(
        attrs={'map_width': 800,'map_height': 500,'default_zoom': 15}
    )
)

其他方式是:

  • 扩展Model.formfield()并将form_class.widget更改为OSMWidget。
  • 实施ModelAdmin.formfield_overrides,仅指定窗口小部件属性。之所以可行,是因为您不必覆盖整个字段,而只需覆盖特定的属性,默认值将来自上面的Model.formfield(),它可以正确设置srid。
  • 使用ModelForm's meta class仅覆盖窗口小部件。与以前的工作方式类似。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。