GeoDjango forms OSMWidget custom templates

GeoDjango forms OSMWidget custom templates

I managed to make GeoDjango HTML form work. Now I am trying to update the template as the default breaks the CSS.

Challenge is I can’t change the template_name.

Specs

django=4.2.7
geos=3.12.1
geoip2=4.7.0
gdal=3.8.1
libgdal-arrow-parquet=3.8.1

Attempts

# templates/custom_openlayers.html -> this is empty file, want to make sure it's loaded 1st. after failing all attempts, I tried templates/gis/custom_openlayers.html, don't work either

# forms.py

import django.contrib.gis.forms as gis_forms
from django.contrib.gis.forms.widgets import OSMWidget


class CustomOSMWidget(OSMWidget):
    template_name = "custom_openlayers.html"
    default_lat = 1.3521
    default_lon = 103.8198


class SomeModelForm(ModelForm):
    class Meta:
        model = SomeModel
        fields = "__all__"
        widgets = {
            # working version
            "degree_decimal": gis_forms.OSMWidget(
                attrs={
                    "default_lat": 1.3521,
                    "default_lon": 103.8198,
                },
            ),
            # attempt 1, add template_name inside OSMWidget's attrs
            "degree_decimal": gis_forms.OSMWidget(
                attrs={
                    "default_lat": 1.3521,
                    "default_lon": 103.8198,
                    "template_name": "custom_openlayers.html",
                },
            ),
            # attempt 2, add template_name inside OSMWidget
            "degree_decimal": gis_forms.OSMWidget(
                attrs={
                    "default_lat": 1.3521,
                    "default_lon": 103.8198,
                },
                "template_name": "custom_openlayers.html",
            ),
            # attempt 3, use custom OSMWidget
            "degree_decimal": CustomOSMWidget(),
        }

    # attempt 4, similar to attempt 1
    degree_decimal = gis_forms.PointField(
        widget=gis_forms.OSMWidget(
            attrs={
                "default_lat": 1.3521,
                "default_lon": 103.8198,
                "template_name": "custom_openlayers.html",
            }
        ),
    )

    # attempt 5, template_name in PointField
    degree_decimal = gis_forms.PointField(
        widget=gis_forms.OSMWidget(
            attrs={
                "default_lat": 1.3521,
                "default_lon": 103.8198,
            }
        ),
        template_name = "custom_openlayers.html",
    )

Attempt 1

            # attempt 1, add template_name inside OSMWidget's attrs
            "degree_decimal": gis_forms.OSMWidget(
                attrs={
                    "default_lat": 1.3521,
                    "default_lon": 103.8198,
                    "template_name": "custom_openlayers.html",
                },
            ),

I am expecting the map to be empty since the custom_openlayers.html is empty. But it gives exact output as the working version. Meaning the template_name is not doing anything

Attempt 2

            # attempt 2, add template_name inside OSMWidget
            "degree_decimal": gis_forms.OSMWidget(
                attrs={
                    "default_lat": 1.3521,
                    "default_lon": 103.8198,
                },
                "template_name": "custom_openlayers.html",
            ),

This fails to load with TypeError: OSMWidget.__init__() got an unexpected keyword argument 'template_name'.

Attempt 3

class CustomOSMWidget(OSMWidget):
    template_name = "custom_openlayers.html"
    default_lat = 1.3521
    default_lon = 103.8198

...
            # attempt 3, use custom OSMWidget
            "degree_decimal": CustomOSMWidget(),
...

This fails to load with django.template.exceptions.TemplateDoesNotExist: custom_openlayers.html. If I commented out template_name, default_lat & default_lon works, meaning this custom OSMWidget is ok.

Attempt 4

    # attempt 4, similar to attempt 1
    degree_decimal = gis_forms.PointField(
        widget=gis_forms.OSMWidget(
            attrs={
                "default_lat": 1.3521,
                "default_lon": 103.8198,
                "template_name": "custom_openlayers.html",
            }
        ),
    )

Exactly same as attempt 2.

Attempt 5

    # attempt 5, template_name in PointField
    degree_decimal = gis_forms.PointField(
        widget=gis_forms.OSMWidget(
            attrs={
                "default_lat": 1.3521,
                "default_lon": 103.8198,
            }
        ),
        template_name = "custom_openlayers.html",
    )

This fails to load with TypeError: Field.__init__() got an unexpected keyword argument 'template_name'

Reference