Джанго, Получить IP местоположение - PullRequest
23 голосов
/ 07 февраля 2010

Я бы хотел перенаправить своих пользователей в определенные области на моем веб-сайте, определив их местоположение по их IP-адресу.

Как лучше всего добиться этого в Django 1.1.1?

Спасибо

Редактировать: Я хочу расположить город в Европе.

Ответы [ 6 ]

30 голосов
/ 07 февраля 2010

GeoDjango выглядит так, как будто оно будет соответствовать вашим потребностям. Я не уверен, как именно вы хотите направлять пользователей, но с помощью GeoIP API вы можете сделать что-то вроде:

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

Документы объясняют вещи очень подробно; Я бы уделил минуту, чтобы прочитать их полностью.

25 голосов
/ 08 февраля 2010

GeoIP уже упоминался, но я считаю pygeoip менее проблематичным в установке и не представляет сложности, если вы хотите встроить его в свое приложение вместо установки в пакеты сайта Python.Тем не менее, он прекрасно работает с бесплатными базами данных MaxMind, например, GeoLite City one.

Пример использования (почти такой же, как для GeoIP):

>>> import pygeoip
>>> gi = pygeoip.GeoIP(GEOIP_DATABASE, pygeoip.GEOIP_STANDARD)
>>> gi.record_by_addr(ip)
{'country': '...', 'country_code': '...', ...}
3 голосов
/ 07 февраля 2010

Кусок торта, и он бесплатен для многих (но не всех) пользователей.

Перейдите на MaxMind.com и следуйте дружественным инструкциям . Начало до конца заняло у меня около 30 минут, чтобы запустить его в приложении Django. Я провел несколько тестов на известных IP, и они очень точны, даже в бесплатной версии.

2 голосов
/ 07 февраля 2010

Это одно из решений: DjangoSnippets ; Кстати, не уверен, почему код ниже не использует urlparse ; но это можно исправить: -)

(Глядя на другие ответы, кажется, у вас есть много вариантов для выбора. Этот вариант может быть не предпочтительным, поскольку он опирается на бесплатную стороннюю службу.)

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"

Примечание от WIPmania : «Использование API бесплатно для любых целей, личных или деловых, если вы делаете менее 10 000 запросов в календарный день. Простой, но мощный API, позволяющий запросить базу данных WorldIP с помощью одной ссылки. "

1 голос
/ 07 февраля 2010

Вы можете создать представление, которое получает IP-адрес пользователя, а затем выдает HTTP-перенаправление, которое заставит их браузер загрузить нужную страницу:

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')
    # ...

Библиотека SubnetTree для Python может оказаться полезной, если вы хотите проверить, находится ли IP в определенном блоке.

0 голосов
/ 03 июля 2019

На основании некоторых бесплатных услуг.

это не быстро, но вы можете добавить больше бесплатных услуг:

Параметры:

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 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",
    },
]

КОД:

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