问题描述
我有一个安装了GIS扩展名的Django 3.1.2
,Postgresql 12
和PostGIS 3
。
在我的模型中,我尝试将PointField
与geography=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}))
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仅覆盖窗口小部件。与以前的工作方式类似。