📜 ⬆️ ⬇️

Django GeoIP - determining the location of the visitor by means of Django Framework

The other day, in one of the projects, we had to screw up the functionality of determining the country of the user's location by IP address. In fact, the task is not difficult if you know how to do it. But the main problem was that the names of states were displayed in Russian and / or English. I will briefly, without unnecessary water and chatter, describe in steps all the installation of the libraries and setting up the project.

To add a Django GIS application to a project, in INSTALLED_APPS it is enough to type 'django.contrib.gis'. So write here . But they do not warn that the entire project then collapses if the necessary libraries and bases are not installed. The article used the materials of official documentation and its own development.


Let's start by installing all the necessary libraries and databases. What do we need?
')


The only unsolved problem is the error of the 'haystack' attached. Therefore it was necessary to temporarily remove it from the project.

All install from source

GEOS installation



$ wget http://download.osgeo.org/geos/geos-3.2.2.tar.bz2 $ tar xjf geos-3.2.2.tar.bz2 $ cd geos-3.2.2 $ ./configure $ make $ sudo make install $ cd .. 


Install PROJ.4



This is a library that converts geospatial data in various coordinate systems.

 $ wget http://download.osgeo.org/proj/proj-4.7.0.tar.gz $ wget http://download.osgeo.org/proj/proj-datumgrid-1.5.zip $ tar xzf proj-4.7.0.tar.gz $ cd proj-4.7.0/nad $ unzip ../../proj-datumgrid-1.5.zip $ cd .. $ ./configure $ make $ sudo make install $ cd .. 


PostGIS installation



PostGIS adds support for the PostgreSQL geographical object, turning it into a database of map data. GEOS and PROJ.4 must be installed before starting to build PostGIS.

 $ wget http://postgis.refractions.net/download/postgis-1.5.2.tar.gz $ tar xzf postgis-1.5.2.tar.gz $ cd postgis-1.5.2 $ ./configure $ make $ sudo make install $ cd .. 


Creating a spatial database template for PostGIS



 $ sudo su - postgres 


Next on the documentation page, download the appropriate script and run. After this, you can create a spatial database by simply specifying template_postgis as a template to use (using the -T option):

 $ createdb -T template_postgis <db name> 


Libraries are installed. Now we swing bases of the countries and cities . Unpack For convenience, I place the files in the directory MEDIA_ROOT / geoip

Now it's time to work with the project settings.py:

 INSTALLED_APPS = ( #.................... 'django.contrib.gis', #.................... ) #.............................................. GEOIP_PATH = os.path.join(MEDIA_ROOT, 'geoip') GEOIP_COUNTRY = 'GeoIP.dat' GEOIP_CITY = 'GeoLiteCity.dat' 


Now you can test. Code for testing, I will not copy-paste. See here docs.djangoproject.com/en/1.3/ref/contrib/gis/geoip/#example . And the documentation, I think, is not worth translating. The next question to pay attention to is Russification. How to get the name of the country in Russian?

For this, I created three models:

 class WorldPart(models.Model): name_ru = models.CharField(max_length=255, verbose_name=_('Name RU'), null=True, blank=True) name_en = models.CharField(max_length=255, verbose_name=_('Name EN'), null=True, blank=True) def __unicode__(self): return self.name_ru class Meta: ordering = ['name_ru', 'name_en',] verbose_name = _('Part of the World') verbose_name_plural = _('Parts of the World') class Country(models.Model): name_ru = models.CharField(max_length=255, verbose_name=_('Name RU'), null=True, blank=True) name_en = models.CharField(max_length=255, verbose_name=_('Name EN'), null=True, blank=True) code = models.CharField(max_length=2, verbose_name=_('Code'), null=True, blank=True) worldpart = models.ForeignKey(WorldPart, verbose_name=_('Part of the World'), null=True, blank=True) flag = models.ImageField(upload_to=os.path.join(settings.STATIC_ROOT, 'img', 'flags'), verbose_name=_('Flag'), null=True, blank=True) is_active = models.BooleanField(verbose_name=_('Is active')) def __unicode__(self): return self.name_ru class Meta: ordering = ['name_ru', 'name_en',] verbose_name = _('Country') verbose_name_plural = _('Countries') class City(models.Model): country = models.ForeignKey(Country, verbose_name=_('Country')) name_ru = models.CharField(max_length=255, verbose_name=_('Name RU'), null=True, blank=True) name_en = models.CharField(max_length=255, verbose_name=_('Name EN'), null=True, blank=True) region = models.CharField(max_length=100, verbose_name=_('Region'), null=True, blank=True) postal_code = models.CharField(max_length=10, verbose_name=_('Postal Code'), null=True, blank=True) latitude = models.CharField(max_length=255, verbose_name=_('Lattitude'), null=True, blank=True) longitude = models.CharField(max_length=255, verbose_name=_('Longitude'), null=True, blank=True) is_active = models.BooleanField(verbose_name=_('Is active')) def __unicode__(self): return self.name_ru class Meta: ordering = ['name_ru', 'name_en',] verbose_name = _('City') verbose_name_plural = _('Cities') 


On the Internet, I found several beautiful bases of countries and cities, and compiled into one with all the fields I needed. I will not post links to databases, knock on the PM.

And this whole mechanism works as follows.

 #   >>> from django.contrib.gis.utils import GeoIP >>> from myapp.models import * >>> g = GeoIP()    >>> cn = g.country('google.com') >>> cn {'country_code': 'US', 'country_name': 'United States'} >>> try: >>> cn_db = Country.objects.get(code=cn['country_code']) >>> except Country.DoesNotExist: >>> pass 


That's all. Perhaps something superfluous, but I tried to point out the main points as concisely as possible. Thank you all for your attention.

Source: https://habr.com/ru/post/179643/


All Articles