How to Create a Django Rest Framework-GIS on Ubuntu 16.04 Server (Part 2)


Step 1: Create Django Models

$ sudo nano geoapi/geoapi/settings.pyINSTALLED_APPS = [
# ...
$ sudo nano geoapi/mygeoapi/
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
from django.contrib.gis.db import models
from django.contrib.postgres.fields import HStoreField
class School(models.Model):
name = models.CharField(max_length=100)
county = models.CharField(max_length=100, null=True)
enrollment = models.IntegerField()
location = models.PointField(srid=4326)
electricity_availability = models.BooleanField(default=False)
emmis_code = models.IntegerField(null=False,default=0)
def __unicode__(self):
class Link(models.Model):
Metadata is stored in a PostgreSQL HStore field, which allows us to
store arbitrary key-value pairs with a link record.
metadata = HStoreField(blank=True, null=True, default=dict)
geo = models.LineStringField()
objects = models.GeoManager()
  1. Name — the name of the school
  2. County — county name of school
  3. Enrollment — number of learners
  4. Emmis code — school unique code
  5. Electricity Availability
  6. Exact location — point(x,y)
$ sudo -u postgres psql -d geoapigeoapi=# create extension hstore;
$ geoapi/ migrate

Step 2: Serializing Django Objects

$ nano geoapi/mygeoapi/
from rest_framework import serializers
from django.contrib.auth.models import User, Group
from mygeoapi.models import School
from rest_framework_gis.serializers import GeoFeatureModelSerializer
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('username', 'id', 'email', 'groups')
class GroupSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Group
fields = ('id', 'name')
class SchoolSerializer(GeoFeatureModelSerializer):
""" A class to serialize locations as GeoJSON compatible data """
class Meta:
model = School
geo_field = 'location'
auto_bbox = True
# you can also explicitly declare which fields you want to include
# as with a ModelSerializer.
fields = ('id', 'name', 'county', 'enrollment', 'location', 'electricity_availability', 'emmis_code')

Step 3: Creating Views

$ sudo nano geoapi/mygeoapi/
from django.contrib.auth.models import User, Group
from rest_framework import viewsets
from .serializers import UserSerializer, GroupSerializer, SchoolSerializer
from .models import School
from rest_framework_gis.filters import DistanceToPointFilter
from rest_framework.decorators import api_view
from rest_framework.response import Response
def api_root(request, format=None):
return Response({
'users': reverse('user-list', request=request, format=format),
'groups': reverse('group-list', request=request, format=format),
'schools': reverse('schools-list', request=request, format=format),
  • Organization of code related to specific HTTP methods (GET, POST, etc.) can be addressed by separate methods instead of conditional branching.
  • Object oriented techniques such as mixins (multiple inheritance) can be used to factor code into reusable components.
class UserViewSet(viewsets.ModelViewSet):
API endpoint that allows users to be viewed or edited.
queryset = User.objects.all().order_by('date_joined')
serializer_class = UserSerializer
class GroupViewSet(viewsets.ModelViewSet):
API endpoint that allows group to be viewed or edited.
class SchoolViewSet(viewsets.ModelViewSet):
queryset = School.objects.all()
serializer_class = SchoolSerializer
distance_filter_field = 'geometry'
filter_backends = (DistanceToPointFilter,)
bbox_filter_include_overlapping = True
$ pip install django-filter

Step 4: Create URLs

$ nano geoapi/mygeoapi/urls.pyfrom django.conf.urls import url, include
from .views import UserViewSet, GroupViewSet, SchoolViewSet, api_root
from rest_framework.urlpatterns import format_suffix_patterns
user_list = UserViewSet.as_view({
'get': 'list'
user_detail = UserViewSet.as_view({
'get': 'retrieve',
'post': 'create',
'put': 'update',
'delete': 'destroy'
group_list = GroupViewSet.as_view({
'get': 'list'
group_detail = GroupViewSet.as_view({
'get': 'retrieve',
'post': 'create',
'put': 'update',
'delete': 'destroy'
school_list = SchoolViewSet.as_view({
'get': 'list'
school_detail = SchoolViewSet.as_view({
'get': 'retrieve',
'post': 'create',
'put': 'update',
'delete': 'destroy'
urlpatterns = [
url(r'^$', api_root),
url(r'^users', user_list, name=user_list),
url(r'^user/(?P<pk>[0-9]+)/$', user_detail, name=user_detail),
url(r'^groups', user_list, name=group_list),
url(r'^groups/(?P<pk>[0-9]+)/$', user_detail, name=group_detail),
url(r'^schools', school_list, name=school_list),
url(r'^schools/(?P<pk>[0-9]+)/$', school_detail, name=school_detail),
] # Login and logout views for the browsable API
urlpatterns += [
url(r'^api-auth/', include('rest_framework.urls',
from django.conf.urls import url, include
from django.contrib import admin
from mygeoapi import views
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)
router.register(r'schools', views.SchoolViewSet)
urlpatterns = [
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^', include(router.urls))

Step 5: Make the mygeoapi App Modifiable in the Admin

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib import admin
from .models import School

Step 6: Restart the Development Server

$ geoapi/ runserver
  1. users
  2. groups
  3. schools





Follow me to keep abreast with the latest technology news, industry insights, and developer trends. Alibaba Cloud website:

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Dynamically Increase Storage Capacity with LVM (Without Rebooting)

Kubernetes Init Containers

Find iOS Memory Leaks with Spider-Man

4 things to know about RPA — Understanding key automation technologies

Communicating Flutter with NodeMCU using MQTT protocol

The ?. Operator in foreach Will Not Protect From NullReferenceException

Flutter + Arduino = Simple heating and ventilation controls.

Introduction to Cloud Foundry

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Alibaba Cloud

Alibaba Cloud

Follow me to keep abreast with the latest technology news, industry insights, and developer trends. Alibaba Cloud website:

More from Medium

DJOSER — Django Rest framework Authentication

Learn Docker from Scratch -Containerizing Django Application with PostgreSQL in Docker

Search/Indexing JSON documents

How to deploy your Django/Python app easily on Ubuntu 20.04 using Uwsgi + Nginx.