在表单提交上对地址进行地理编码?

时间:2010-05-02 21:16:57

标签: python django django-forms geocoding

试图围绕django形式和django做事方式。我想创建一个基本的Web表单,允许用户输入地址并将该地址进行地理编码并保存到数据库中。

我创建了一个位置模型:

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 个答案:

答案 0 :(得分: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 ','

答案 1 :(得分: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)

答案 2 :(得分:1)

你也可以使用django.db.models.signals.pre_save - 信号!

http://docs.djangoproject.com/en/dev/topics/signals/查看Django的信号文档。

答案 3 :(得分:0)

我正在做同样的事情 可能是红豆杉正在寻找类似的文字

# 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}) 

答案 4 :(得分: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