Геокодирование адреса при отправке формы?
пытаясь обернуть голову вокруг форм django и способа django делать вещи. Я хочу создать базовую веб-форму, которая позволяет пользователю вводить адрес и геокодировать этот адрес и сохранять его в базе данных.
Я создал модель местоположение:
class Location(models.Model):
address = models.CharField(max_length=200)
city = models.CharField(max_length=100)
state = models.CharField(max_length=100, null=True)
postal_code = models.CharField(max_length=100, null=True)
country = models.CharField(max_length=100)
latitude = models.DecimalField(max_digits=18, decimal_places=10, null=True)
longitude = models.DecimalField(max_digits=18, decimal_places=10, null=True)
и определил форму:
class LocationForm(forms.ModelForm):
class Meta:
model = models.Location
exclude = ('latitude','longitude')
на мой взгляд я использую form.save()
для сохранения формы. Это работает и сохраняет адрес в базе данных.
Я создал модуль для геокодирования адреса. Я не уверен, что способ django делать вещи, но я думаю, на мой взгляд, прежде чем я сохраню форму, мне нужно геокодировать адрес и установить lat и long. Как установить широту и долготу перед сохранением?
5 ответов
вы можете переопределить метод save модели. Я геокодировать данные перед сохранением. Это использование googleapi, но его можно соответствующим образом изменить.
import urllib
def save(self):
location = "%s, %s, %s, %s" % (self.address, self.city, self.state, self.zip)
if not self.latitude or not self.longitude:
latlng = self.geocode(location)
latlng = latlng.split(',')
self.latitude = latlng[0]
self.longitude = latlng[1]
super(Marker, self).save()
def geocode(self, location):
output = "csv"
location = urllib.quote_plus(location)
request = "http://maps.google.com/maps/geo?q=%s&output=%s&key=%s" % (location, output, settings.GOOGLE_API_KEY)
data = urllib.urlopen(request).read()
dlist = data.split(',')
if dlist[0] == '200':
return "%s,%s" % (dlist[2], dlist[3])
else:
return ','
обновление для Google Maps API v3:
import json
import urllib.parse,
from decimal import Decimal
def save(self):
if not self.lat or not self.lng:
self.lat, self.lng = self.geocode(self.address)
super(Location, self).save()
def geocode(self, address):
address = urllib.parse.quote_plus(address)
maps_api_url = "?".join([
"http://maps.googleapis.com/maps/api/geocode/json",
urllib.parse.urlencode({"address"=address, "sensor"=False})
])
response = urllib.urlopen(maps_api_url)
data = json.loads(response.read().decode('utf8'))
if data['status'] == 'OK':
lat = data['results'][0]['geometry']['location']['lat']
lng = data['results'][0]['geometry']['location']['lng']
return Decimal(lat), Decimal(lng)
вы также можете использовать django.db.models.signals.pre_save
-сигнал!
взгляните на документацию сигнала Django в http://docs.djangoproject.com/en/dev/topics/signals/.
Я делаю то же самое, как это может быть, тисовое ищете что-то similarstrong текст
# forms.py
from django.contrib.gis.utils import GeoIP
class registerForm(forms.ModelForm):
class Meta:
model=register
fields = ('Availability', 'Status')
def save(self,ip_address, *args, **kwargs):
g = GeoIP()
lat, lon = g.lat_lon(ip_address)
user_location = super(registerForm, self).save(commit=False)
user_location.latitude = lat
user_location.longitude = lon
user_location.save(*args, **kwargs)
и мои взгляды
#views.py
if request.method == "POST":
ip_address=request.META['REMOTE_ADDR']
rform = registerForm(data = request.POST)
if rform.is_valid():
register = rform.save(commit=False)
register.user=request.user
register.save(ip_address)
return render_to_response('home.html')
else:
rform = registerForm()
return render_to_response('status_set.html',{'rform':rform})
подобно другим ответам:
def geocode(address, city, state, zip_code):
try:
location_param = urllib.request.quote("%s, %s, %s, %s" % (address, city, state, zip_code))
url_request = "http://maps.googleapis.com/maps/api/geocode/json?address=%s&sensor=false" % location_param
result = requests.get(url_request)
data = result.json()
location = data['results'][0]['geometry']['location']
lat = location['lat']
lng = location['lng']
return lat, lng
except Exception:
return None