readthedocs: geoip2.readthedocs.io/en/latest/
pypi: pypi.org/project/geoip2/
Content:
MaxMind
- Create an account in Maxmind: MaxMind.
- After logging in, click Manage license keys in the left menu.
- Click the button Generate a new license key.
- Make sure to save your license key securely.
| GeoLite ASN | Identifies the ASN (Autonomous System Number) and the organization owning the IP. |
| GeoLite City | Provides detailed IP location including city, region, and country. |
| GeoLite Country | Provides only the country associated with an IP. |
Downloading a database:
- Click Download files in the left menu.
- For this tutorial we will be downloading: GeoLite City as GZIP
Getting the Data in Django
pip install geoip2
from django.urls import path
from .views import *
urlpatterns = [
path("", index.as_view(), name="index"),
]
from django.views.generic import TemplateView
from django.conf import settings
import geoip2.database
class index(TemplateView):
template_name = 'polls/index.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
ip = self.request.META.get('HTTP_X_FORWARDED_FOR')
if ip: ip = ip.split(',')[0].strip()
else: ip = self.request.META.get('REMOTE_ADDR', '8.8.8.8')
if ip in ("127.0.0.1", "::1"): ip = "8.8.8.8"
reader = geoip2.database.Reader(settings.BASE_DIR / 'GeoLite2-City.mmdb')
response = reader.city(ip)
location = {
'ip': ip,
'country': response.country.name,
'country_iso_code': response.country.iso_code,
'city': response.city.name,
'latitude': response.location.latitude,
'longitude': response.location.longitude
}
reader.close()
context['location'] = location
print(location)
return context
<table>
<tr> <td>ip</td> <td>{{location.ip}} </td> </tr>
<tr> <td>city</td> <td>{{location.city}} </td> </tr>
<tr> <td>country</td> <td>{{location.country}} </td> </tr>
<tr> <td>country_iso_code</td> <td>{{location.country_iso_code}} </td> </tr>
<tr> <td>latitude</td> <td>{{location.latitude}} </td> </tr>
<tr> <td>longitude</td> <td>{{location.longitude}} </td> </tr>
</table>
Always-On task
Since IP address allocations can change, MaxMind updates these files twice a week, on Tuesdays and Fridays.
MaxMind Update Schedule
Therefore, it’s important to have a mechanism in place to regularly update the database files.
The script below can be scheduled as an Always-On task, triggered on those days.
from pathlib import Path
import shutil
import tarfile
import requests
BASE_DIR = Path(__file__).resolve().parent
id = "xxxxx"
key = "xxxxx"
url = 'https://download.maxmind.com/geoip/databases/GeoLite2-City/download?suffix=tar.gz'
auth = (id, key)
save_path = BASE_DIR / 'GeoLite2-City.tar.gz'
response = requests.get(url, auth=auth, stream=True)
if response.status_code != 200:
print(f"Download failed, HTTP Code: {response.status_code}")
with save_path.open('wb') as f:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
with tarfile.open(save_path, 'r:gz') as tar:
tar.extractall(path=BASE_DIR)
save_path.unlink()
extracted_folders = list(BASE_DIR.glob("GeoLite2-City_*"))
if not extracted_folders:
raise FileNotFoundError("Extracted folder GeoLite2-City not found.")
extracted_folder = extracted_folders[0]
mmdb_source = extracted_folder / "GeoLite2-City.mmdb"
mmdb_dest = BASE_DIR / "GeoLite2-City.mmdb"
if mmdb_dest.exists():
mmdb_dest.unlink()
shutil.move(str(mmdb_source), str(mmdb_dest))
shutil.rmtree(extracted_folder)
print("Database GeoLite2-City updated.")
Tested with: Django 5.2 geoip2==5.1.0
12 Aug. 2025
|
Last Updated: 03 Dec. 2025
|
jaimedcsilva Related