views:

493

answers:

5

Hello I would like to redirect my users to specific location areas in my website, by detecting their location from their IP address.

What would be the best way to achieve this under Django 1.1.1 ?

Thanks

Edit: I want city based locationing on europe.

+1  A: 

Piece of cake, and it's free for many (but not all) uses.

Go to MaxMind.com and follow the friendly instructions. Start to finish it took me about 30 minutes to have this running in a Django app. I did a number of tests on known IPs and they are very accurate, even in the free version.

Peter Rowell
+2  A: 

GeoDjango looks like it will suit your needs. I'm not sure exactly how you would want to direct users, but using the GeoIP API, you can do something like:

from django.contrib.gis.utils import GeoIP
g = GeoIP()
ip = request.META.get('REMOTE_ADDR', None)
if ip:
    city = g.city(ip)['city']
else:
    city = 'Rome' # default city

# proceed with city

The Docs explain things in great detail; I would take a moment to read through them thoroughly.

Nick Presta
+1  A: 

You could create a view which gets the user's IP and then issues an HTTP redirect which will cause their browser to load the page you want:

def redirect_based_on_ip(request):
    ip = request.meta['REMOTE_ADDR']
    if ip == SOMETHING:
        return HttpResponseRedirect('/something')
    elif ip == SOMETHING_ELSE:
        return HttpResponseRedirect('/something_else')
    # ...

You might find the SubnetTree library for Python helpful if you want to test to see if an IP is in a particular block.

David Underhill
+1  A: 

This is one solution, from DjangoSnippets; btw, not sure why the code below doesn't use urlparse; but that could be fixed :-)

(Looking at the other answers, it seems you have plenty of options to choose from. This option may not be preferred because it relies on a free 3rd party service.)

from urllib2 import urlopen, Request
import re, socket
from django.conf import settings

domain_re = re.compile('^(http|https):\/\/?([^\/]+)')
domain = domain_re.match(settings.SITE_URL).group(2)

def getUserCountry(ip):
    url = "http://api.wipmania.com/" + ip + "?" + domain
    socket.setdefaulttimeout(5)
    headers = {'Typ':'django','Ver':'1.1.1','Connection':'Close'}
    try:
        req = Request(url, None, headers)
        urlfile = urlopen(req)
        land = urlfile.read()
        urlfile.close()
        return land[:2]
    except Exception:
        return "XX"

Note from WIPmania: "Using API is free for any purpose, personal or business, if you are making fewer than 10.000 requests per calendar day. A simple yet powerful API allowing you to query the WorldIP database with a single link."

Adam Bernier
You could maintain a cache of already known IPs somewhere, thus not having to poke WIPmania each time somebody hits your site.
frgtn
+3  A: 

GeoIP is already mentioned, but I find pygeoip less troublesome to install and no-brainer if you want to embed it in you application instead of installing in Python's site-packages. Still, it works great with free MaxMind databases, e.g GeoLite City one.

Example of use (almost the same as for GeoIP):

    >>> import pygeoip
    >>> gi = pygeoip.GeoIP(GEOIP_DATABASE, pygeoip.GEOIP_STANDARD)
    >>> gi.record_by_addr(ip)
    {'country': '...', 'country_code': '...', ...}
Tomasz Zielinski
Definitely easier to setup.
Nick Presta