Beginners Guide To Geo-Django in Django

GeoDjango is a built-in application that is included as a contrib module in Django. It’s actually a complete framework itself that can also be used separately from Django. It provides a toolbox of utilities for building GIS web applications.

Requirements:

Project Setup:

$ mkdir dj_gis && cd dj_gis
$ python3 -m venv env
$ source env/bin/activate
$ pip install django djangorestframework django-leaflet geopy psycopg2-binary 
$ django-admin.py startproject config
$ python manage.py startapp my_geo_app

setting.py

#config/settings.py

INSTALLED_APPS = [
    "django.contrib.gis",
    "my_geo_app",
    "rest_framework",
]

urls.py

#config/urls.py

from django.contrib import admin
from django.urls import path
from django.urls.conf import include


urlpatterns = [
    path("admin/", admin.site.urls),
    path("api/v1/", include("my_geo_app.urls")),
]

include url.py file on my_geo_app app

from django.urls import path

urlpatterns = []

Let’s create a model app/models.py

from django.db import models
from django.contrib.gis.db import models # GeoDjango


class Casino(models.Model):
    name = models.CharField(max_length=255)
    address = models.CharField(max_length=255)
    created_at = models.DateTimeField(auto_now_add=True)
    location = models.PointField(null=True) # lat and long point fields

    def __str__(self):
        return self.name

let’s create a serializer and views for our model.

from location.models import Casino
from rest_framework import serializers


class CasinoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Casino

        fields = ("id", "name", "address", "location")

        extra_kwargs = {"location": {"read_only": True}}

my_geo_app/views.py

from location.serializers import CasinoSerializer
from django.shortcuts import render
from rest_framework import generics
from .models import Casino

from django.contrib.gis.geos import Point
from geopy.geocoders import Nominatim

geolocator = Nominatim(user_agent="casino")


class ListCreateGenericViews(generics.ListCreateAPIView):
    queryset = Casino.objects.all()
    serializer_class = CasinoSerializer

    def perform_create(self, serializer):
        address = serializer.initial_data["address"]
        g = geolocator.geocode(address)
        lat = g.latitude
        lng = g.longitude
        pnt = Point(lng, lat)
        print(pnt)
        serializer.save(location=pnt)


class HotelUpdateRetreiveView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Casino.objects.all()
    serializer_class = CasinoSerializer

    def perform_update(self, serializer):
        address = serializer.initial_data["address"]
        g = geolocator.geocode(address)
        lat = g.latitude
        lng = g.longitude
        pnt = Point(lng, lat)
        print(pnt)
        serializer.save(location=pnt)

geopy makes it easy for Python developers to locate the coordinates of addresses, cities, countries, and landmarks across the globe using third-party geocoders and other data sources.

Read how to automate email sending task using celery

urls.py

from django.urls import path
from .views import CasinoUpdateRetreiveView, ListCreateGenericViews

urlpatterns = [
    path("casinos", ListCreateGenericViews.as_view()),
    path(
        "casinos/<str:pk>",
        CasinoUpdateRetreiveView.as_view(),
    ),
]

Database and leaflet settings

DATABASES = {
    "default": {
        "ENGINE": "django.contrib.gis.db.backends.postgis",
        "NAME": "locator",
        "USER": "locator",
        "PASSWORD": "locator",
        "HOST": "http://127.0.0.1:8000",
        "PORT": "5432",
    }
}

LEAFLET_CONFIG = {
    # "SPATIAL_EXTENT": (5.0, 44.0, 7.5, 46),
    "DEFAULT_CENTER": (13.3888599 52.5170365), #set your corordinate
    "DEFAULT_ZOOM": 16,
    "MIN_ZOOM": 3,
    "MAX_ZOOM": 20,
    "DEFAULT_PRECISION": 6,
    "SCALE": "both",
    "ATTRIBUTION_PREFIX": "anshu is cool",
}

Register a model to admin

from django.contrib import admin
from leaflet.admin import LeafletGeoAdmin

from .models import Casino


@admin.register(Casino)
class HotelAdmin(LeafletGeoAdmin):
    list_display = ("id", "name", "address", "location", "created_at")

Everything is good to go, just make the necessary migrations and run the app

python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver

Cheers!!!

This Post Has One Comment

Leave a Reply