Index de l'article

Création du modèle d'une couche de points

Nous allons créer notre 1ère couche de points grâce à GeoDjango. Cela en commençant par en créer le modèle, Django et son ORM sauront ensuite générer la table correspondante.

GeoDjango est un module déjà nativement présent dans Django, puisque pour l'utiliser il nous suffira de l'appeler. Cependant GeoDjango nécessite certaines librairies que vous avez sans doute déjà installeés.

Éditons le fichier models.py de notre application carto déjà créée. Remplacez son éventuel contenu par ces lignes :

from django.contrib.gis.db import models
import datetime
from django.utils import timezone

class Sample(models.Model):
# Champs classiques
name = models.CharField("Name", max_length=100)
author = models.CharField("Author", max_length=100)
pub_date = models.DateTimeField("Moment")
type = models.CharField("Type", max_length=100)
description = models.CharField("Description", max_length=100)
structure = models.CharField("Structure", max_length=100)

# Champ geometrique
geom = models.PointField("Location")

# Chaine du modele
def __str__(self):
return self.name

Attention à l'indentation, qui doit être respectée (4 espaces). Mais si besoin Python vous renverra des erreurs avec leurs lignes concernées.

Le 1er paragraphe contient nos éventuelles importations d'options nécessaires (les from et import). Remarquez que nous avons remplacé notre modèle par défaut par django.contrib.gis.db, c'est notre façon de demander à ce fichier de modèles d'utiliser GeoDjango.

En effet juste en-dessous, un objet Sample définit une table et ses champs, et l'un de ces champs est justement de type géométrique (PointField).

Remarquez que nous ne prenons pas la peine de créer un champ id, Django s'en occupera pour nous. Tant mieux...

Le dernier paragraphe définit la chaine du modèle. Remarquez que name n'est pas un mot spécial, mais reprend bien le champ name que vous vous apprêtez à créer.

L'absence d'accent dans mes commentaires n'est pas anodin, en effet Python est très à cheval sur les encodages et les tracasseries qu'il y a autour. Je ne prendrais donc aucun risque ici.

À ce stade la génération de la table ne donnera rien, car si le fichier de modèles de notre application carto est bien au courant qu'il doit utiliser le module GeoDjango, Django lui-même ne le sait pas encore. Il ne sait même pas que notre application carto existe. Allons lui dire.

Déclarations des applications installées

Sous Django 1.6 vous allez déclarer vos apps dans le fichier settings.py de votre projet en ajoutant les deux dernières lignes de ce bloc des INSTALLED_APPS. Votre bloc ressemble maintenant à cela :

INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.gis',
'carto',
)

Sous Django 1.9 vous déclarez vos applications personnelles légèrement différemment. De cette façon pour notre application carto

'carto.apps.CartoConfig',

Encore une fois : attention à l'indentation !

Votre projet Django sait maintenant qu'il doit utiliser le module GIS de Django (django.contrib.gis) et qu'une application est déjà présente (carto).

Vous pouvez maintenant générer la table (syncdb ou migrate selon votre version de Django, voir le Mémo Django/GeoDjango/Python).

Une table carto_sample a été créée, préfixée du nom de notre application, et contenant bien nos champs (et un champ id).

Remarquez que le champ geom a été parfaitement créée, quelque soit notre version de Postgres, avec des types de contraintes dont je ne connaissais même pas l'existence (trois CHECK automatiques semble-t-il, du SRID, de la dimension et du type de géométrie). De même si vous êtes sur une version 9.0 de Postgres, remarquez que Django a correctement ajouté une entrée à la table geometry_columns. Sans plus d'information de notre part, Django a choisi le SRID 4326, correspondant à une projection mondiale courante sur le web.

Django et son ORM font vraiment bien le boulot ! Mais au fait : où est notre interface ?