2010-05-02 2 views
7

Попытка обернуть мою голову вокруг форм джанго и способ джанго делать вещи. Я хочу создать базовую веб-форму, которая позволяет пользователю вводить адрес и иметь этот адрес, геокодированный и сохраненный в базе данных.Геокодирование адреса при отправке формы?

Я создал модель Расположение:

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(), чтобы сохранить форму. Это работает и сохраняет адрес в базе данных.

Я создал модуль для геокодирования адреса. Я не уверен, что способ делать что-то джанго, но, на мой взгляд, прежде чем сохранить форму, мне нужно геокодировать адрес и установить lat и long. Как установить широту и долготу перед сохранением?

ответ

8

Вы можете переопределить метод сохранения модели. Я геокодирую данные перед сохранением. Это использование 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 ',' 
+0

Большое спасибо Я попробую это и вернусь к вам. Что вы берете на geocode(), возвращая кортеж или объект Coordinate вместо строки? – User

+0

Это отличная идея. Было бы лучше очистить данные перед возвратом. Обычно мне нравится делать такие вещи. Я оставил его таким образом из-за того, как я реорганизовал исходное уравнение. Я думал, что CSV весь путь просто потому, что так он возвращается из Google, но мне нравится, как вы думаете. Я собираюсь реорганизовать это, чтобы вернуть объект. – digitaldreamer

+0

Обновление для API Карт Google v3 ниже. –

0

я делаю то же самое, как этот может быть тис ищут что-то 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}) 
3

Обновление для 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) 
0

Как и другие ответы:

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 
Смежные вопросы