在Django/Python中规范街道地址

在Django/Python中规范街道地址,python,django,django-models,django-forms,geopy,Python,Django,Django Models,Django Forms,Geopy,我有一个Django表单,其中一个字段是街道地址的TextInput 我想规范化数据。例如: >> normalize('420 East 24th St.') '420 E. 24th Street' >> normalize('221 Amsterdam Av') '221 Amsterdam Ave.' >> normalize('221 Amsterdam Avenue') '221 Amsterdam Ave.' def clean(self)

我有一个Django表单,其中一个字段是街道地址的
TextInput

我想规范化数据。例如:

>> normalize('420 East 24th St.')
'420 E. 24th Street'

>> normalize('221 Amsterdam Av')
'221 Amsterdam Ave.'

>> normalize('221 Amsterdam Avenue')
'221 Amsterdam Ave.'
def clean(self):
    # check address via some self-defined helper function
    matches = my_helper_address_matcher(address, city, state, zip)
    if not matches:
        raise forms.ValidationError("Your address couldn't be found...")
    elif len(matches) > 1:
        # add javascript into error so the user can select 
        # the address that matches? maybe there is a cleaner way to do this
        raise forms.ValidationError('Did you mean...') 
或者类似的。我已经在使用地理编码了。也许这会有帮助


还有:我应该在哪里正常化?在数据库模型或表单字段的clean函数中?

一个选项是使用Geopy在Yahoo或Google Maps之类的人上查找地址,然后返回他们匹配的地址的完整地址。您可能需要注意返回地址中的公寓号码是否被截断(例如,“221阿姆斯特丹大道330号”变为“221阿姆斯特丹大道”)。此外,您还将获得城市/州/国家信息,用户也可能缩写或拼写错误

如果存在多个匹配项,您可以提示用户反馈他们的地址。在没有匹配项的情况下,您还可以让用户知道,并可能允许无论如何保存地址,这取决于有效地址的重要性以及您对地址查找提供程序的有效性的信任程度

关于在form vs.model中进行规范化,我不知道Django的首选方式是什么,但我更喜欢表单,例如:

>> normalize('420 East 24th St.')
'420 E. 24th Street'

>> normalize('221 Amsterdam Av')
'221 Amsterdam Ave.'

>> normalize('221 Amsterdam Avenue')
'221 Amsterdam Ave.'
def clean(self):
    # check address via some self-defined helper function
    matches = my_helper_address_matcher(address, city, state, zip)
    if not matches:
        raise forms.ValidationError("Your address couldn't be found...")
    elif len(matches) > 1:
        # add javascript into error so the user can select 
        # the address that matches? maybe there is a cleaner way to do this
        raise forms.ValidationError('Did you mean...') 

您可以在模型(或某些helpers.py文件)中抛出此查找函数,以防在其他区域重复使用它

这就是我最终解决此问题的方式(没有双关语):

然后我使用
Place.display\u address
在模板中。这允许我在数据库中保留用户提交的原始数据,而无需修改,并且在需要标准化显示版本时只需使用
display\u address


开放供评论/建议。

最可靠的方法是使用真正的地址验证服务。它不仅将根据USPS标准(请参阅)标准化(规范化)地址组件,而且还将确保地址是真实的

充分披露:我为SmartyStreets工作,它提供了这样一个平台。下面是一些非常简单的python示例代码,展示了如何通过HTTP GET请求使用我们的服务:


我最近创建了一个python模块,它的StreetAddressFormatter可用于规范化您的地址

抱歉:美国。特别是纽约。我正在开发一个必须处理地址的库,虽然SmartyStreets看起来有点贵(尽管免费层相当慷慨),而且可能会给我的库增加一点延迟(需要往返服务器),但它看起来是一个非常棒的服务。我想我可能会支持它。继续努力!谢谢正如您所知,我们是地理分布的,请求在离用户位置最近的数据中心处理,这减少了延迟。警告一句,我使用过这些服务,但它们并不十分准确,尤其是在公寓和分区中。而且,如果不是不可能的话,它们很难用于处理大批量产品。