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:
- Postgres(Or MySql, MongoDB)
- PostGIS extension needs to be installed on Postgres
- QGIS GeoDjango Dependencies or install Geospatial libraries GEOS, GDAL, and PROJ.4,
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.
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!!!