Enhancing registering experience with django.contrib.localflavor
Usability is very much about little stuff. That kind of things that you normally don’t even think about. Here is a small snippet of code that I used in a project where I wanted to pre-select a users location (city) on a registering form.
Hostip.info has the necessary data and a very straightforward API. The newly-added django.contrib.localflavor package in Django helps with the other part of the data.
This is the small method for geolocating the IP address:
def _get_city_for_ip(ip):
"""
Uses hostip.info to get a city name from IP
"""
import urllib
import mimetools
url = 'http://api.hostip.info/get_html.php?ip=%s' % ip
fp = urllib.urlopen(url)
headers = mimetools.Message(fp, 0)
fp.close()
return headers.dict['city'].lower()
and a stripped-down view code for generating and displaying the form:
class ProfileForm(forms.Form):
from django.contrib.localflavor.fi.fi_municipalities import MUNICIPALITY_CHOICES
...
cities = [('none_selected', 'Please Select a city')] + list(MUNICIPALITY_CHOICES)
location = forms.ChoiceField(required=False, choices=cities)
def profile(request):
""" Presents and validates the profile form """
u = request.user
# Only do geolocating if the profile has no location info
location = u.get_profile().location
if len(location) < 2:
location = _get_city_for_ip(request.META['REMOTE_ADDR'])
form = ProfileForm(initial={'location': location})
return render_to_response('users/profile_form.html', locals())
I’m sure this code can be tweaked quite a bit from this. Currently it uses Finnish localflavor code to get a list of Finnish municipalities, add a ‘Please Select a city’ choice to the beginning of it, and then tries to match a geolocated city against it. If no match is found, it defaults to ‘Please Select a city’. But if a match is found, user is presented a select field with the City matching his current IP-address pre-selected.












