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.