Django REST Framework GIS
Django REST Framework GIS (DRF-GIS) provides geographic add-ons for Django Rest Framework, enabling the creation of REST APIs for geospatial data. It offers GIS-specific fields and serializers, including GeoJSON support. The current version is 1.2.0. Releases are somewhat irregular, with major updates typically annually, and minor versions released as needed.
Warnings
- breaking Version 1.1.0 dropped support for Python versions 3.6, 3.7 and Django versions 2.2, 3.0, 3.1, 4.0. It also dropped support for `djangorestframework < 3.12`.
- breaking Version 0.14.0 introduced a dependency on `django-filters >= 2.0`, which itself requires Python >= 3.4. Ensure your Python version meets this requirement if using filtering.
- gotcha Prior to version 1.0.0, Django versions >= 3.2 would raise a `default_app_config` deprecation warning when using `djangorestframework-gis`.
- gotcha Before version 0.16.0, passing additional arguments via `style` to `GeometryField` might have been unintentionally overridden. This was fixed to allow proper customization.
- gotcha Prior to version 0.16.0, `djangorestframework-gis` had issues with the representation of empty geometries, potentially leading to errors or incorrect output.
- gotcha The deserialization of the `id_field` was fixed in version 1.0.0. If you experienced issues with `id_field` during deserialization (e.g., when creating or updating objects), this might have been the cause.
- gotcha For `GeoFeatureModelSerializer` to correctly handle models without a geometry field, you must be using version 1.1.0 or higher.
Install
-
pip install djangorestframework-gis -
pip install psycopg2-binary
Imports
- GeometryField
from rest_framework_gis.fields import GeometryField
- GeoFeatureModelSerializer
from rest_framework_gis.serializers import GeoFeatureModelSerializer
- DistanceToPointOrderingFilter
from rest_framework_gis.filters import DistanceToPointOrderingFilter
Quickstart
import os
import django
from django.conf import settings
from django.db import models
from django.contrib.gis.db import models as gis_models
from rest_framework_gis.serializers import GeoFeatureModelSerializer
from rest_framework.generics import ListCreateAPIView
# --- Minimal Django setup for demonstration ---
# In a real Django project, these would be in settings.py, models.py, views.py, urls.py
if not settings.configured:
settings.configure(
INSTALLED_APPS=[
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.gis', # Essential for DRF-GIS
'rest_framework',
'rest_framework_gis',
'myapp' # Placeholder for our app, add it to INSTALLED_APPS
],
DATABASES={
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'mydatabase_test',
'USER': os.environ.get('DB_USER', 'postgres'),
'PASSWORD': os.environ.get('DB_PASSWORD', ''),
'HOST': os.environ.get('DB_HOST', 'localhost'),
'PORT': os.environ.get('DB_PORT', '5432'),
}
},
SECRET_KEY=os.environ.get('DJANGO_SECRET_KEY', 'a-very-secret-key-for-dev-and-testing'),
ROOT_URLCONF='__main__',
USE_TZ=True,
TIME_ZONE='UTC',
STATIC_URL='/static/'
)
django.setup()
# --- Example Model (myapp/models.py) ---
# Define a custom AppConfig for 'myapp' if needed, or simply ensure 'myapp' is in INSTALLED_APPS
# and Django can find your models.
class Place(gis_models.Model):
name = models.CharField(max_length=100)
location = gis_models.PointField(srid=4326) # WGS84 latitude/longitude
def __str__(self):
return self.name
class Meta:
app_label = 'myapp' # Required for models defined outside an app directory
# --- Example Serializer (myapp/serializers.py) ---
class PlaceSerializer(GeoFeatureModelSerializer):
class Meta:
model = Place
geo_field = 'location'
fields = ('id', 'name', 'location')
# --- Example View (myapp/views.py) ---
class PlaceListCreateAPIView(ListCreateAPIView):
queryset = Place.objects.all()
serializer_class = PlaceSerializer
# --- Example URLs (project_root/urls.py or myapp/urls.py) ---
# from django.urls import path
# from myapp.views import PlaceListCreateAPIView
#
# urlpatterns = [
# path('api/places/', PlaceListCreateAPIView.as_view(), name='place-list-create'),
# ]
# This block checks if the components are defined. In a real project,
# you would configure URLs and run the Django development server.
assert issubclass(PlaceSerializer, GeoFeatureModelSerializer)
assert issubclass(PlaceListCreateAPIView, ListCreateAPIView)
print("DRF-GIS model, serializer, and view components defined successfully.")