GeoDjango PointField admin visualization

2019-05-07 06:00发布

问题:

I was wondering how I could change the default PointField visualization (the Openstreetmap) in admin so that I could enter simple latitude/longitude instead of select a point on the map?

I looked at this one Latitude/longitude widget for pointfield? but could not get it working in any way in Django 1.6b4

Thanks

回答1:

As Bibhas says you can override the widget used for the field, but the simple text input may not be usefull. So here is an example with a full widget that can be used for PointField of geodjango:

class LatLongWidget(forms.MultiWidget):
    """
    A Widget that splits Point input into latitude/longitude text inputs.
    """

    def __init__(self, attrs=None, date_format=None, time_format=None):
        widgets = (forms.TextInput(attrs=attrs),
                   forms.TextInput(attrs=attrs))
        super(LatLongWidget, self).__init__(widgets, attrs)

    def decompress(self, value):
        if value:
            return tuple(value.coords)
        return (None, None)

    def value_from_datadict(self, data, files, name):
        mylat = data[name + '_0']
        mylong = data[name + '_1']

        try:
            point = Point(float(mylat), float(mylong))
        except ValueError:
            return ''

        return point

And now you can override your model Admin:

from django.contrib.gis.db import models as geomodels
class CompanyAdmin(admin.ModelAdmin):
    list_display = ('name', 'approval', 'company_view',)
    list_filter = ('approval',)
    formfield_overrides = {
        geomodels.PointField: {'widget': LatLongWidget},
    }


回答2:

You can override a widget with another in Django admin. From the documentation -

from django.db import models
from django.contrib import admin

# Import our custom widget and our model from where they're defined
from myapp.widgets import RichTextEditorWidget
from myapp.models import MyModel

class MyModelAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.TextField: {'widget': RichTextEditorWidget},
    }

This overrides TextField with RichTextEditorWidget. Just find the field type for point field and override it with TextField.



回答3:

In case you are new to gis, and you don't know where point is defined, the LatLongWidget above needs to know what Point is. You can import it like this:

from django.contrib.gis.geos.point import Point


回答4:

In this post I approach this issue by using two extra "Decimal Fields" in the ModelForm. This way, the Latitude and Longitude fields appear in the admin for the user's convenience without affecting the database, whatsoever.

They always reflect the relevant values if a PointField exists while they can update them or create them if the PointField does not exist.