Art*_*urM 11 django django-forms geodjango
PointField是否有一个小部件作为单独的纬度/经度输入?就像DateTimeField的SplitDateTimeWidget一样.
这是我的工作自定义字段和小部件:
class LatLongWidget(forms.MultiWidget):
"""
A Widget that splits Point input into two latitude/longitude boxes.
"""
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(reversed(value.coords))
return (None, None)
class LatLongField(forms.MultiValueField):
widget = LatLongWidget
srid = 4326
default_error_messages = {
'invalid_latitude' : _('Enter a valid latitude.'),
'invalid_longitude' : _('Enter a valid longitude.'),
}
def __init__(self, *args, **kwargs):
fields = (forms.FloatField(min_value=-90, max_value=90),
forms.FloatField(min_value=-180, max_value=180))
super(LatLongField, self).__init__(fields, *args, **kwargs)
def compress(self, data_list):
if data_list:
# Raise a validation error if latitude or longitude is empty
# (possible if LatLongField has required=False).
if data_list[0] in validators.EMPTY_VALUES:
raise forms.ValidationError(self.error_messages['invalid_latitude'])
if data_list[1] in validators.EMPTY_VALUES:
raise forms.ValidationError(self.error_messages['invalid_longitude'])
# SRID=4326;POINT(1.12345789 1.123456789)
srid_str = 'SRID=%d'%self.srid
point_str = 'POINT(%f %f)'%tuple(reversed(data_list))
return ';'.join([srid_str, point_str])
return None
Run Code Online (Sandbox Code Playgroud)
答案非常适合构建您自己的解决方案,但如果您想要一个看起来不错且易于使用的简单解决方案,请尝试:http : //django-map-widgets.readthedocs.io/en/latest/index.html
你可以:
@Ramast,以更Python的方式处理相同的问题。我已将更改合并到我的代码中,随时进行改进感觉很好。
这是我设法(最后)保留纬度和经度的单独字段而不必将其保存在数据库中的方式,因为值已经保存在PointField中。
这个想法是:
models.py
from django.contrib.gis.db import models as geomodels
class Entry(geomodels.Model):
point = geomodels.PointField(
srid=4326,
blank=True,
)
Run Code Online (Sandbox Code Playgroud)
管理员
from myapp.forms import EntryForm
from django.contrib import admin
class EntryAdmin(admin.ModelAdmin):
form = EntryForm
admin.site.register(Entry, EntryAdmin)
Run Code Online (Sandbox Code Playgroud)
表格
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
Run Code Online (Sandbox Code Playgroud)