03 Des modèles ..
Les modèles Django
A l'instar de nombreux frameworks web, les modèles Django sont des classes qui héritent d'une classe du framework (la classe .. Model!).
En faisant hériter vos modèles de cette fameuse classe vous leur conférez automatiquement toutes les propriétés et méthodes relatives au modèles (gestion de l'ORM, ..).
Syntaxe de déclaration d'un modèle
Vous l'avez d'ores et déjà compris, c'est au sein du fichier models.py de notre application que nous allons implémenter tous nos modèles. Voici la syntaxe :
models.py:
from django.db import models
class MyModel(models.Model):
a_text_field = models.CharField(max_length=150)
Par défault tout nos modèles seront créer dans le fichier models.py, il s'agit d'une convention de Django. Sachez simplement que si par la suite, notamment sur une application de grande taille, vous souhaitez diviser vos fichiers de modèles en plusieurs fichiers, c'est tout à fait possible.
Types de champs disponibles
En créant un modèle Django, nous allons utiliser le système d'ORM du framework. Django propose ainsi quelques types de champs (~ d'attributs) disponibles pour utilisation dans nos modèles.
Voici une liste non-exhaustive:
- CharField: Un champ de texte, typiquement mappé vers un « VARCHAR » en BDD.
- TextField: Un champ de texte long, typiquement mappé vers un « TEXT » en BDD.
- ForeignKey: Une référence à un objet d'un autre modèle. En BDD, il est représenté par un entier désignant l'ID de la ligne cible.
- ManyToManyField: Une référence à plusieurs objets d'un autre modèle. En BDD, il est représenté à l'aide d'une table d'association.
- BooleanField: Un champ booléen.
- URLField: Un champ de texte représentant une URL, typiquement mappé vers un « VARCHAR » en BDD.
- SlugField: Un champ de texte représentant un slug, c'est à dire une chaîne de caractère destinée à être utilisée dans une URL.
- IntegerField: Un nombre entier.
- DateTimeField: Une date et une heure.
Nous n'allons pas lister ici tous les champs qu'il est possible d'utiliser dans un modèle. Une liste exhaustive est disponible sur la documentation officielle de Django, section Model field reference.
Chaque type de champ admet un certain nombre de paramétrages, que Django appelle des options. Nous n'allons pas non-plus tous les lister, mais voici les plus utilisés :
- null=True|False: Permet de spécifier si le champ correspondant en BDD peut être NULL ou pas.
- blank=True|False: Permet de spécifier si, dans les formulaires de l'application, le champ peut être laissé vide ou pas.
- max_length=[in]: Permet de spécifier la longueur maximale d'un CharField (généralement, la limite est de 255 caractères).
- default=[int|str|boolean|..]: Permet de spécifier une valeur par défaut pour le champ
Voici un exemple d'utilisation de ces options dans le cadre de la déclaration d'un modèle:
from django.db import models
class MyModel(models.Model):
a_text_field = models.CharField(max_length=150, null=True,
blank=True, default="Hello")
Modèles de notre appplication
Voici une première version de nos modèles:
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import User
class Type(models.Model):
name = models.CharField(max_length=150)
slug = models.SlugField()
class Game(models.Model):
name = models.CharField(max_length=150)
slug = models.SlugField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
release_date = models.DateTimeField(auto_now_add=True)
picture = models.ImageField()
types = models.ManyToManyField(Type)
Création des tables de la base de données
Nous avons à présent nos modèles, mais aucune base pour stocker les données de ceux-ci. Pour pallier ce problème, nous allons faire dans le classique : nous utiliserons une base de données relationnelle.
Pour éviter d'avoir à installer un serveur de BDD comme PostgreSQL ou MySQL, nous allons utiliser SQLite. Nous utilisons un ORM nous serons donc libre, plus tard, notamment si le projet obtient le succès qu'il mérite ☺, de switcher très simplement vers un autre SGBD, en modifiant juste la configuration de notre projet.
Pour utiliser SQLite, nous n'avons rien de spécial à faire, si ce n'est de fournir le nom du fichier de BDD à Django dans notre fichier de configuration.
Modification du fichier settings.py
Pour préciser à Django que nous souhaitons utiliser SQLite nous n'avons rien à faire, par défault la commande startproject initialise le fichier settings.py avec la variable DATABASES:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
Profitons également d'être dans le fichier settings.py pour modifier quelques configurations. Modifions la section INSTALLED_APPS pour indiquer à notre projet Django que nous souhaitons utiliser notre application games_review:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'games_review',
]
Ajoutez à la fin du fichier de configuration les élèments suivants:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Sauvegarder le fichier settings.py
Nous allons également ajouter les urls vers les fichiers statiques et les médias (fichiers uploadés via le back end) dans le fichier urls.py:
from django.urls import include, path
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Sauvegardez également le fichier urls.py
Migrations
Django sait maintenant où écrire ses données !
Nous allons maintenant lui demander de créer les tables de la base de données pour nous, à partir des informations que nous lui avons fournies dans les modèles de nos applications (en l’occurrence, de notre application, puisque notre projet n'en comporte qu'une pour le moment).
Nous allons encore une fois utiliser la commande python manage.py
, avec l'argument makemigrations :
$ python manage.py makemigrations
Voici le retour de cette commande :
Migrations for 'games_review':
games_review/migrations/0001_initial.py:
- Create model Game
- Create model Type
- Add field types to game
A cette étape aucune données n'a été écrite en base, nous venons simplement de créer une migration (c'est à dire un script python qui décrit les opérations à effecturer sur la base de données) qui permettra de modifier la structure de notre base de données en conséquence.
Une fois la migration réalisée, il faut l'appliquer. Pour ce faire on utilise toujours la commande python manage.py avec l'argument migrate:
$ python manage.py migrate
Voici le retour de Django:
Operations to perform:
Apply all migrations: admin, auth, contenttypes, games_review, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying games_review.0001_initial... OK
Applying sessions.0001_initial... OK
Notre base de données est à présent créée, et comporte les tables nécessaires au fonctionnement de notre application. Si vous listez le contenu du répertoire de votre projet, vous devez y voir un nouveau fichier, nommé db.sqlite3. C'est notre base de données SQLite !
Vous avez remarqué que Django a créé d'autres tables que celles relatives à notre application ! Ce sont les tables utiles aux autres applications mentionnées dans notre fichier settings.py.
Par curiosité, vous pouvez ouvrir votre base de données SQLite pour voir ce qu'elle contient. Plusieurs outils existent : à moindre frais, vous pouvez utiliser SQLite Manager !
Conclusion
Notre projet et notre application prennent forme ! Nous allons maintenant voir comment disposer, en quelques secondes, d'une interface d'administration puissante permettant d'éditer nos données : c'est l'objet du tutoriel sur le scaffolding avec Django.