Reputation: 855
I have a Django 3.1.2
with GIS extension installed, PostgreSQL 12
and PostGIS 3
.
In my model I'm trying to use a PointField
with geography=True
to store real-world coordinates:
location = models.PointField(geography=True, srid=4326, blank=False, null=False, verbose_name=_("Lat/Lon coordinates"))
In the admin menu I'm using the OSMWidget to enter coordinates:
location = forms.PointField(widget=forms.OSMWidget(attrs={'map_width': 800, 'map_height': 500, 'default_zoom': 15}))
When this is saved Django runs into the following SQL error:
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: ...", "location") VALUES (15, 10, 'Start', ST_Transfo...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
ST_Transform()
is used to transform geometry points (which is used as data type if geography=False
is used for the PointField
). But I'm not sure what's required to make it work with geography.
Upvotes: 0
Views: 643
Reputation:
Since you override the PointField it has no srid set and ST_Transform is used to convert the geom to the right spatial reference.
There's several ways to correctly change the widget, but I'll give you the simplest one with your current code:
location = forms.PointField(
srid=4326,
widget=forms.OSMWidget(
attrs={'map_width': 800, 'map_height': 500, 'default_zoom': 15}
)
)
The other ways are:
Model.formfield()
and change form_class.widget
to OSMWidget.ModelAdmin.formfield_overrides
and only specify the widget attribute. This works because you do not have to override the entire field, but just specific attributes, the defaults will come from Model.formfield()
above, which correctly sets the srid.Upvotes: 2