In this recipe, you have seen how quick and efficient it is to assemble a back office application using Django, one of the most popular Python web frameworks; this is thanks to its object-relational mapper, which automatically created the database tables needed by your application and an automatic API to manage (insert, update, and delete) and query the entities without using SQL.
Thanks to the GeoDjango library, two of the application models, County and Sighting, have been geo-enabled with their introduction in the database tables of geometric PostGIS fields.
You have customized the powerful automatic administrative interface to quickly assemble the back-office pages of your application. Using the Django URL Dispatcher, you have defined the URL routes for your application in a concise manner.
As you may have noticed, what is extremely nice about the Django abstraction is the automatic implementation of the data-access layer API using the models. You can now add, update, delete, and query records using Python code, without having any knowledge of SQL. Try this yourself, using the Django Python shell; you will select an animal from the database, add a new sighting for that animal, and then finally delete the sighting. You can investigate the SQL generated by Django, behind the scenes, any time, using the django.db.connection class with the following command:
(chp09-env-bis)$ python manage.py shell
>>> from django.db import connection
>>> from datetime import datetime
>>> from sightings.models import Sighting, Animal
>>> an_animal = Animal.objects.all()[0]
>>> an_animal
<Animal: Lion>
>>> print connection.queries[-1]['sql']
SELECT "sightings_animal"."id", "sightings_animal"."name", "sightings_animal"."image" FROM "sightings_animal" ORDER BY "sightings_animal"."name" ASC LIMIT 1'
my_sight = Sighting(date=datetime.now(), description='What a lion I have seen!', rate=1, animal=an_animal, geometry='POINT(10 10)')
>>> my_sight.save()
print connection.queries[-1]['sql']
INSERT INTO "sightings_sighting" ("date", "description", "rate", "animal_id", "geometry") VALUES ('2013-06-12 14:37:36.544268-05:00', 'What a lion I have seen!', 1, 2, ST_GeomFromEWKB('\x0101000020e610000000000000000024400000000000002440'::bytea)) RETURNING "sightings_sighting"."id"
>>> my_sight.delete()
>>> print connection.queries[-1]['sql']
DELETE FROM "sightings_sighting" WHERE "id" IN (5)
Do you like Django as much as we do? In the next recipe, you will create the frontend of the application. The user will be able to browse the sightings in a map, implemented with the Leaflet JavaScript library. So keep reading!