Same Con to Hoyci — too many choices —

A blog about Web development, usability and AI.

Enhancing registering experience with django.contrib.localflavor

 by Ville Säävuori

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. 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 to get a city name from IP
    import urllib
    import mimetools
    url = '' % ip
    fp = urllib.urlopen(url)
    headers = mimetools.Message(fp, 0)
    return headers.dict['city'].lower()

and a stripped-down view code for generating and displaying the form:

class ProfileForm(forms.Form):
    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.

Follow @uninen on Twitter