Нормализация уличных адресов в Django/Python
у меня есть форма 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 ответов
самый надежный способ сделать это-использовать добросовестную службу проверки адресов. Он не только стандартизирует (нормализует) компоненты адреса в соответствии со стандартами USPS (см. публикации 28), но вы также будете уверены, что адрес реальный.
полное раскрытие информации: я работаю на SmartyStreets, которая предоставляет именно такой сервис. Вот очень простой пример кода python, который показывает, как использовать наш сервис через HTTP GET запрос:
https://github.com/smartystreets/LiveAddressSamples/blob/master/python/street-address.py
недавно я создал улица-адрес модуль python и его StreetAddressFormatter можно использовать для нормализации вашего адреса.
одним из вариантов было бы использовать 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 файл) в случае, если вы хотите использовать его в других областях
вот как я закончил, обращаясь к этому (без каламбура):
### 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
когда я хочу нормализованную версию дисплея.
открыть для комментариев / предложений.