8

我有一个 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.'

或类似的东西。我已经在使用geopy进行地理编码。也许这可能会有所帮助?

另外:我应该在哪里标准化?在数据库模型中还是在表单域的清理功能中?

4

4 回答 4

4

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

于 2012-11-27T19:06:25.733 回答
4

这就是我最终解决这个问题的方式(不是双关语):

### models.py ###

def normalize_address_for_display(address):

    display_address = string.capwords(address)

    # Normalize Avenue
    display_address = re.sub(r'\b(Avenue|Ave.)\b', 'Ave', display_address)

    # Normalize Street
    display_address = re.sub(r'\b(Street|St.)\b', 'St', display_address)

    # ...and other rules...

    return display_address

class Store(models.Model):

    name = models.CharField(max_length=32)
    address = models.CharField(max_length=64)
    city = models.CharField(max_length=32)
    state = models.CharField(max_length=2)
    zipcode = models.CharField(max_length=5)

    @property
    def display_address(self):
        return normalize_address_for_display(self.address)

然后我Place.display_address在模板中使用。这使我可以将原始用户提交的数据保留在数据库中而无需修改,并且仅display_address在我想要标准化显示版本时使用。

打开评论/建议。

于 2011-02-07T04:51:15.020 回答
4

最可靠的方法是利用真实地址验证服务。它不仅会根据 USPS 标准(参见出版物 28)对地址组件进行标准化(规范化),而且您还将确定地址是真实的。

全面披露:我在 SmartyStreets 工作,它提供的就是这样的服务。下面是一些非常简单的 Python 示例代码,展示了如何通过 HTTP GET 请求使用我们的服务:

https://github.com/smartystreets/LiveAddressSamples/blob/master/python/street-address.py

于 2011-10-26T14:32:36.350 回答
2

一种选择是使用 Geopy 在 Yahoo 或 Google Maps 等人上查找地址,然后返回与其匹配的地址的完整地址。您可能需要注意返回地址中的公寓号码是否被截断(例如,“221 Amsterdam Av #330”变为“221 AMSTERDAM AVENUE”)。此外,您还将获得城市/州/国家/地区信息,用户可能还会缩写或拼写错误。

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

关于在表单与模型中进行这种规范化,我不知道首选的 Django 做事方式是什么,但我的偏好是在表单中,例如:

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 文件)中抛出这个查找函数,以防你想在其他领域重用它

于 2011-01-29T18:41:34.173 回答