PK10
PK10

Reputation: 362

Error while setting up geoip for my site "GeoIP path must be a valid file or directory"

For my django app I am trying to store log of login location by amdin.

I created a middleware and trying use from "django.contrib.gis.utils import GeoIP" to get the latitude and longitude values of geo locations.

But getting error something like:

GeoIPException at /admin/

GeoIP path must be a valid file or directory.

code: trackware.py

from django.contrib.gis.utils import GeoIP
from core.models import Log # your simple Log model

def get_ip(request):
   xff = request.META.get('HTTP_X_FORWARDED_FOR')
   if xff:
      return xff.split(',')[0]
   return request.META.get('REMOTE_ADDR')

class UserLocationLoggerMiddleware(object):

    def process_request(self, request):
        if request.user and request.user.is_superuser:
            # Only log requests for superusers,
            # you can control this by adding a setting
            # to track other user types
            ip = get_ip(request)
            g = GeoIP()
            lat,long = g.lat_lon(ip)
            Log.objects.create(request.user, ip, lat, long)

changes that I made in settings.py:

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',

#custom middleware
    'smartDNA.trackware.UserLocationLoggerMiddleware',
)

BASE_DIR = os.path.abspath(os.path.dirname(__file__))
GEOIP_PATH =os.path.join(BASE_DIR, 'geoip')

models.py:

class Log(models.Model):
    user = models.CharField(verbose_name="User",max_length=32)
    ip=models.IPAddressField(verbose_name="IP")
    lat= models.DecimalField(verbose_name="Lat",max_digits=10,decimal_places=1)
    long= models.DecimalField(verbose_name="Long",max_digits=10,decimal_places=1)

register model in admin.py:

admin.site.register(Log)

What is the mistake that I am doing and solution please....

Upvotes: 6

Views: 10446

Answers (5)

Kayemba Luwaga
Kayemba Luwaga

Reputation: 47

For your Django project, you should download the GeoLite2 City database in the GeoIP2 Binary (.mmdb) format. This format is compatible with the django.contrib.gis.geoip2 module.

Here are the steps:

  • Download the GeoLite2 City Database
  • Go to the GeoLite2 City section on the MaxMind website.
  • Download the GZIP file: Download GZIP under GeoLite2 City.
  • Extract the GZIP file then extract the .mmdb file from the downloaded GZIP file.
  • Place the extracted .mmdb file in a directory within your Django project, for example, geoip.
  • Update Your Django Settings:
  • Update your settings.py to include the path to the .mmdb file.

Details:

  • Download the GeoLite2-City.mmdb.gz file from MaxMind.
  • Extract the .mmdb file:
gunzip GeoLite2-City.mmdb.gz

Directory Structure:

Assuming you place the extracted file in a directory named geoip within your project root, your directory structure would look like this:

my_project/
├── geoip/
│   └── GeoLite2-City.mmdb
├── my_project/
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
│   └── ...
├── manage.py
└── ...

Update settings.py:

Add the path to the GeoIP database in your Django settings:

import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
GEOIP_PATH = os.path.join(BASE_DIR, 'geoip/GeoLite2-City.mmdb')

Upvotes: 0

Mayank Gupta
Mayank Gupta

Reputation: 41

I have changed this

GEOIP_PATH =os.path.join(BASE_DIR, 'geoip')

to

GEOIP_PATH =os.path.join(BASE_DIR, 'geoip/')

Upvotes: 1

Denis Gavrielov
Denis Gavrielov

Reputation: 11

I had a similar problem and then I changed

GEOIP_PATH =os.path.join(BASE_DIR, 'geoip') to GEOIP_PATH =os.path.join('geoip').

Hope it helps.

Upvotes: 0

user3672754
user3672754

Reputation:

I was having the same problem and I solved it in this way:

this is my project..

> root
    > app
        settings.py
        urls.py
        ...
    > static
    > application
    > templates
    manage.py

1) DOWNLOAD GeoLiteCountry and GeoLiteCity.dat.gz

2) Create a folder in root called geoip and Put both files inside. Be sure that both files are renamed GeoIPCity.dat and GeoIP.dat

3) Specify the path in your settings file GEOIP_PATH = os.path.join(BASE_DIR, 'geoip')

4) make a test

python manage.py shell
>>> from django.contrib.gis.geoip import GeoIP
>>> g = GeoIP()
>>> g.city('72.14.207.99')
..

and if it stills not working, take a look to the g instance to find out the pointing location:

>>> print g._city_file
/home/foo/root/geoip/GeoIPCity.dat
>>> print g._country_file
/home/foo/root/geoip/GeoIP.dat

*In case you get an empty string, try to find the bug. Do not try to re-assign the path by modifying the instance g._city_file=/home/foo/Desktop/GeoIP.0.dat, it won't work !

Upvotes: 16

Burhan Khalid
Burhan Khalid

Reputation: 174624

From the documentation:

In order to perform IP-based geolocation, the GeoIP object requires the GeoIP C libary and either the GeoIP Country or City datasets in binary format (the CSV files will not work!). These datasets may be downloaded from MaxMind. Grab the GeoLiteCountry/GeoIP.dat.gz and GeoLiteCity.dat.gz files and unzip them in a directory corresponding to what you set GEOIP_PATH with in your settings.

Make sure you have done the above, otherwise the system does not know how to map IPs to locations.

Upvotes: 8

Related Questions