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

Prerequisites

Step 1: Create Django Models

$ sudo nano geoapi/geoapi/settings.pyINSTALLED_APPS = [
# ...
'mygeoapi',
]
$ sudo nano geoapi/mygeoapi/models.py
# -*- 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):
return self.name
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()
$ sudo -u postgres psql -d geoapigeoapi=# create extension hstore;
$ geoapi/manage.py migrate

Step 2: Serializing Django Objects

$ nano geoapi/mygeoapi/serializers.py
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/views.py
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
@api_view(['GET'])
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),
})
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.
"""
queryset=Group.objects.all()
serializer_class=GroupSerializer
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',
namespace='rest_framework')),
]
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'^admin/', admin.site.urls),
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
admin.site.register(School)

Step 6: Restart the Development Server

$ geoapi/manage.py runserver 0.0.0.0:8000
http://server_domain_or_IP:8000

Conclusion

--

--

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