Geodjango管理员,如何将PointField显示为非地图形式

9
这可能是一个愚蠢的问题,但我找不到任何明确的答案。
我该如何更改Django Admin中的显示,使Pointfield不像OpenLayer地图一样显示,而是像普通的输入字段一样显示。我需要看到经度和纬度以便调试。
我需要更改字段类型吗?小部件?
谢谢!

可能是GeoDjango PointField管理可视化的重复问题。 - Ilmari Karonen
2个回答

12

更新

最终,我成功地实现了在不必将纬度和经度存储到数据库中的情况下,保持它们的分离状态,因为这些值已经保存在“PointField”中。

思路如下:

  • 如果我们正在插入新条目,则会使用纬度和经度字段来设置“PointField”
  • 如果我们打开一个现有的“PointField”条目,则会使用它来提供相关表单字段中的纬度和经度值。

models.py

from django.contrib.gis.db import models as geomodels


class Entry(geomodels.Model):
    point = geomodels.PointField(
        srid=4326,
        blank=True,
        )

admin.py

from myapp.forms import EntryForm
from django.contrib import admin


class EntryAdmin(admin.ModelAdmin):
    form = EntryForm


admin.site.register(Entry, EntryAdmin)

forms.py

from django import forms
from myapp.models import Entry
from django.contrib.gis.geos import Point


class MarketEntryForm(forms.ModelForm):

    latitude = forms.FloatField(
        min_value=-90,
        max_value=90,
        required=True,
    )
    longitude = forms.FloatField(
        min_value=-180,
        max_value=180,
        required=True,
    )

    class Meta(object):
        model = MarketEntry
        exclude = []
        widgets = {'point': forms.HiddenInput()}

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        coordinates = self.initial.get('point', None)
        if isinstance(coordinates, Point):
            self.initial['longitude'], self.initial['latitude'] = coordinates.tuple

    def clean(self):
        data = super().clean()
        latitude = data.get('latitude')
        longitude = data.get('longitude')
        point = data.get('point')
        if latitude and longitude and not point:
            data['point'] = Point(longitude, latitude)
        return data

PointField的源代码我们可以看出,它的表单类使用了OpenLayersWidget,该类继承自BaseGeometryWidget
结论是在这个类中,变量display_raw默认设置为False
如果在yourapp/admin.py中将其设置为True,您将获得一个带有纬度、经度和其他数据的文本框,对于调试非常有用。
from django.contrib.gis import admin
from yourapp.models import YourClass
from django.contrib.gis import forms
from django.contrib.gis.db import models    


class YourClassAdminForm(forms.ModelForm):
    your_attribute = forms.PointField(widget=forms.OSMWidget(attrs={
            'display_raw': True}))

class YourClassAdmin(admin.GeoModelAdmin):
    form = YourClassAdminForm


admin.site.register(YourClass, YourClassAdmin)

还有一种方法可以同时拥有地图和手动插入经度/纬度(不仅适用于调试)。

这个想法是使用FloatFields来插入经度/纬度,并使用插入的数据更新PointField。


2

在Django admin中,您可以用另一个小部件覆盖小部件。 文档 -

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},
    }

这将使用RichTextEditorWidget覆盖TextField。只需找到指向字段的类型并用TextField覆盖它即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接