我有一个非常简单的Django表单,它由一个字段组成 - “地址”:
class AddressSearchForm(forms.Form):
"""
A form that allows a user to enter an address to be geocoded
"""
address = forms.CharField()
我可能甚至不需要使用表单,因为我没有保存这些数据 - 我只是将它收集起来用于搜索。但是,我想执行验证:
def clean_address():
data = self.cleaned_data
g = geocoders.Google()
try:
place, (lat,lng) = g.geocode(data['address'])
except (GQueryError):
raise forms.ValidationError('Please enter a valid address')
except (GeocoderResultError, GBadKeyError, GTooManyQueriesError):
raise forms.ValidationError('There was an error geocoding your address. Please try again')
except:
raise forms.ValidationError('An unknown error occured. Please try again')
此外,我想使用此地理编码结果将Point对象传递给我的视图:
from django.contrib.gis.geos import Point
point = Point(lng, lat)
我的问题是,如何将地址和点数据传递给我的视图?我可以只传递地址然后在视图中重新编码,但那将是重复的代码。那么,如何从表单中传递点对象?我应该使用隐藏的字段吗?其他建议?提前谢谢。
答案 0 :(得分:1)
我不是django专家,但这就是我所做的:
def clean_homeaddress(self):
in_address = self.cleaned_data['homeaddress']
place, self.cleaned_data['homelocation'] = address_to_latlng(in_address, True)
return place
哦,顺便说一句,看看下面的包装器。 geocoders.Google无法正确处理unicode字符串。下面有一个简单的黑客删除所有非ascii字符。我还没有时间找出更好的解决方案。
def address_to_latlng(address, return_address = False):
""" returns GoeDjango POINT string value for given location (address)
if return_address is true, it'll return 2-tuple: (address, point)
otherwise it returns point
"""
g = geocoders.Google()
try:
#TODO: not really replace, geocode should use unicode strings
address = address.encode('ascii', 'replace')
place, latlng = g.geocode(address)
except Exception as e:
raise ValidationError(_(u"Incorrect location provided"))
point = 'POINT(%f %f)' % tuple(reversed(latlng))
if return_address:
return (place, point)
return point
根据要求,有完整的代码。这个会将位置打印到输出控制台,它会在会话中保留“已清理”(由Google返回)地址,以便在每次显示表单时将其显示给用户。
class GeoForm(forms.Form):
address = forms.CharField()
def clean_address(self):
in_address = self.cleaned_data['address']
place, self.cleaned_data['location'] = address_to_latlng(in_address, True)
return place
class GeoView(FormView):
form_class = GeoForm
template_name = 'geoview.html'
success_url = '/sandbox/geo'
def get_initial(self):
if '_address' in self.request.session:
return {'address': self.request.session['_address']}
return {}
def form_valid(self,form):
print form.cleaned_data['location']
self.request.session['_address'] = form.cleaned_data['address']
return super(GeoView, self).form_valid(form)