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.