Django, Retrieve IP location
Asked Answered
S

7

30

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.

Stepmother answered 7/2, 2010 at 19:57 Comment(1)
How do you want to distinguish users? Based on Country? On continent? Language spoken? etc?Rockery
R
39

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.

Rockery answered 7/2, 2010 at 20:9 Comment(2)
still the best option for Geoip tracing in 2015 ?Beatty
This has been deprecated since Django 1.9. Use GeoIP2 instead (docs.djangoproject.com/en/1.10/ref/contrib/gis/geoip2)Suppliant
M
25

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': '...', ...}
Mackmackay answered 7/2, 2010 at 21:24 Comment(3)
This was extremely practical for Windows. Highly recommend.Rawdon
Free to download MaxMind legacy databases: Country, CityOdelsting
pygeoip is now deprecated.Altercation
J
3

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."

Johns answered 7/2, 2010 at 20:31 Comment(2)
You could maintain a cache of already known IPs somewhere, thus not having to poke WIPmania each time somebody hits your site.Sarajane
How to save the location of user in DataBase ?Unthinking
H
1

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.

Hominy answered 7/2, 2010 at 20:11 Comment(0)
B
1

Based on some free services.

it's not fast, but you can add more free services:

settings:

IPCOUNTRY_APYKEY = [
{# free tier 2 querys per second
    "url": "http://api.ipinfodb.com/v3/ip-country/?ip={ip}&key={key}&format=json",
    "params": {
        "key": "*****************************",
    },
    "fieldname": "countryCode",
}, 
{# free tier 150 querys per minute and https is not suported in free tier
    "url": "http://ip-api.com/json/{ip}?fields=2",
    "params": {},
    "fieldname": "countryCode",
}, 
{# free tier 1.500 queries per day
    "url": "https://api.ipdata.co/{ip}?api-key={key}",
    "params": {
        "key": "*****************************",
    },
    "fieldname": "country_code",
}, 
{# free tier 10.000 queries per month and https is not suported in free tier
    "url": "http://api.ipstack.com/{ip}?access_key={key}",
    "params": {
        "key": "*****************************",
    },
    "fieldname": "country_code",
},
{# free tier 10.000 queries per month and https is not suported in free tier
    "url": "http://api.ipapi.com/{ip}?access_key={key}",
    "params": {
        "key": "*****************************",
    },
    "fieldname": "country_code",
},

]

CODE:

import json
import urllib3

from django.conf import settings

for service in settings.IPCOUNTRY_APYKEY:
    url = service["url"].format(ip=ip,**service["params"])
    headers = {'Type': 'django', 'Ver': '1.1.1', 'Connection': 'Close'}
    urllib3.disable_warnings()
    http_call = urllib3.PoolManager()
    try:
        r = http_call.request('GET', url, headers=headers, timeout=1.0)
        if r.status == 200:
            json_response = json.loads(r.data.decode("utf-8"))
            print(json_response[service["fieldname"]])
    except Exception as e:
        pass
    
return None
Boll answered 3/7, 2019 at 8:52 Comment(0)
A
0

I have made SO answer where I am using Cloudflare CDN, they provide extra header with GEO location of each visitor. Advantage is that we don't have to install any external library or make any API call. Redirection can be achieved by Django middleware.

Aksoyn answered 30/8, 2021 at 14:20 Comment(0)
T
0

You can achieve this by making use of IP2Location Python library and IP2Location BIN database. First, purchase a commercial IP2Location database from https://www.ip2location.com/database/ip2location or download a free IP2Location LITE database from https://lite.ip2location.com/. And also install the IP2Location Python library by using this command: pip install IP2Location

After that, open your views.py, and add the following code into the file:

from django.http import HttpResponse
from django.shortcuts import redirect
import IP2Location

database = IP2Location.IP2Location(YOUR_DATABASE_PATH)

def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    if ip == '127.0.0.1': # Only define the IP if you are testing on localhost.
        ip = '8.8.8.8'
    return ip

def redirect_view(request):
    ip = get_client_ip(request)
    rec = database.get_all(ip)
    if rec.city == 'London': # Or any other city name
        response = redirect('PATH_REDIRECT_TO')
        return response

def redirectsucess_view(request):
    return HttpResponse('Welcome!')

After that, open the urls.py, and add the following codes into the urlpatterns list:

path('redirect/', views.redirect_view),
path('PATH_REDIRECT_TO/', views.redirectsucess_view)
Tman answered 28/9, 2022 at 7:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.