Introduction
Dans le précédent tutoriel, » Comment créer une application Django et la connecter à une base de données « , nous avons couvert comment créer une base de données MySQL, comment créer et démarrer une application Django, et comment la connecter à une base de données MySQL.
Dans ce tutoriel, nous allons créer les modèles Django qui définissent les champs et comportements des données de l’application Blog que nous allons stocker. Ces modèles cartographient les données de votre application Django vers la base de données. C’est ce que Django utilise pour générer les tables de la base de données via son API de mappage objet-relationnel (ORM), appelée « modèles ».
Prérequis
Ce tutoriel fait partie de la série de développement Django et est une continuation de cette série.
Si vous n’avez pas suivi cette série, nous faisons les hypothèses suivantes :
- Vous avez Django version 4 ou une version ultérieure installée.
- Vous avez connecté votre application Django à une base de données. Nous utilisons MySQL, et vous pouvez réaliser cette connexion en suivant la deuxième partie de la série Django, « Comment créer une application Django et la connecter à une base de données« .
- Vous travaillez avec un système d’exploitation de type Unix, de préférence un serveur cloud Ubuntu 22.04, car c’est le système sur lequel nous avons effectué nos tests. Si vous souhaitez configurer Django dans un environnement similaire, veuillez vous référer à notre tutoriel, « Comment installer Django et configurer un environnement de développement sur Ubuntu 22.04« .
Étant donné que ce tutoriel traite principalement des modèles Django, vous devriez pouvoir suivre même si votre configuration est quelque peu différente.
Étape 1 — Créer une application Django
Pour rester cohérent avec la philosophie de modularité de Django, nous allons créer une application Django au sein de notre projet qui contient tous les fichiers nécessaires à la création du site web du blog.
Chaque fois que nous commençons à travailler en Python et Django, nous devrions activer notre environnement virtuel Python et nous déplacer dans le répertoire racine de notre application. Si vous avez suivi la série, vous pouvez le faire en tapant la commande suivante.
- cd ~/my_blog_app
- . env/bin/activate
- cd blog
Ensuite, exécutons cette commande :
- python manage.py startapp blogsite
Cela créera notre application avec un répertoire blogsite
.
À ce stade de la série de tutoriels, vous aurez la structure de répertoire suivante pour votre projet :
my_blog_app/
└── blog
├── blog
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-38.pyc
│ │ ├── settings.cpython-38.pyc
│ │ ├── urls.cpython-38.pyc
│ │ └── wsgi.cpython-38.pyc
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── blogsite
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
└── manage.py
Le fichier sur lequel nous nous concentrerons pour ce tutoriel sera le fichier models.py
, qui se trouve dans le répertoire blogsite
.
Étape 2 — Ajouter le modèle de publication
Tout d’abord, nous devons ouvrir et éditer le fichier models.py
afin qu’il contienne le code pour générer un modèle Post
. Un modèle Post
contient les champs de base de données suivants :
title
— Le titre de l’article de blog.slug
— Où les URL valides sont stockées et générées pour les pages web.content
— Le contenu textuel de l’article de blog.created_on
— La date à laquelle l’article a été créé.author
— La personne qui a rédigé l’article.
Maintenant, déplacez-vous dans le répertoire où se trouve le fichier models.py
.
- cd ~/my_blog_app/blog/blogsite
Utilisez la commande cat
pour afficher le contenu du fichier dans votre terminal.
- cat models.py
Le fichier devrait contenir le code suivant, qui importe les modèles, ainsi qu’un commentaire décrivant ce qui doit être placé dans ce fichier models.py
.
from django.db import models
# Créez vos modèles ici.
À l’aide de votre éditeur de texte favori, ajoutez le code suivant au fichier models.py
. Nous utiliserons nano
comme éditeur de texte, mais vous pouvez utiliser celui que vous préférez.
- nano models.py
Dans ce fichier, le code pour importer l’API des modèles est déjà ajouté, nous pouvons donc supprimer le commentaire qui suit. Ensuite, nous importerons slugify
pour générer des slugs à partir de chaînes, User
de Django pour l’authentification, et reverse
de django.urls
pour nous donner une plus grande flexibilité dans la création d’URL.
from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
from django.urls import reverse
Ensuite, ajoutez la méthode de classe sur la classe de modèle que nous appellerons Post
, avec les champs de base de données suivants : title
, slug
, content
, created_on
et author
. Ajoutez-les sous vos déclarations d’importation.
...
class Post(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(unique=True, max_length=255)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
author = models.TextField()
Ensuite, nous ajouterons la fonctionnalité pour la génération de l’URL et la fonction pour sauvegarder le post. C’est crucial, car cela crée un lien unique pour correspondre à notre publication unique.
...
def get_absolute_url(self):
return reverse('blog_post_detail', args=[self.slug])
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
Maintenant, nous devons indiquer au modèle comment les publications doivent être triées et affichées sur la page web. La logique pour cela sera ajoutée à une classe Meta
interne imbriquée. La classe Meta
contient généralement d’autres logiques importantes du modèle qui ne sont pas liées à la définition des champs de la base de données.
...
class Meta:
ordering = ['created_on']
def __unicode__(self):
return self.title
Enfin, nous ajouterons le modèle Comment
à ce fichier. Cela implique d’ajouter une autre classe nommée Comment
avec models.Models
dans sa signature et les champs de base de données suivants définis :
name
— Le nom de la personne qui poste le commentaire.email
— L’adresse e-mail de la personne qui poste le commentaire.text
— Le texte du commentaire lui-même.post
— Le billet avec lequel le commentaire a été fait.created_on
— L’heure à laquelle le commentaire a été créé.
...
class Comment(models.Model):
name = models.CharField(max_length=42)
email = models.EmailField(max_length=75)
website = models.URLField(max_length=200, null=True, blank=True)
content = models.TextField()
post = models.ForeignKey(Post, on_delete=models.CASCADE)
created_on = models.DateTimeField(auto_now_add=True)
À ce stade, models.py
sera complet. Assurez-vous que votre fichier models.py
correspond au suivant :
from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
from django.urls import reverse
class Post(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(unique=True, max_length=255)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
author = models.TextField()
def get_absolute_url(self):
return reverse('blog_post_detail', args=[self.slug])
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
class Meta:
ordering = ['created_on']
def __unicode__(self):
return self.title
class Comment(models.Model):
name = models.CharField(max_length=42)
email = models.EmailField(max_length=75)
website = models.URLField(max_length=200, null=True, blank=True)
content = models.TextField()
post = models.ForeignKey(Post, on_delete=models.CASCADE)
created_on = models.DateTimeField(auto_now_add=True)
N’oubliez pas de sauvegarder et de fermer le fichier. Si vous utilisez nano, vous pouvez le faire en tapant CTRL
et X
, puis Y
, puis ENTER
.
Avec le fichier models.py
configuré, nous pouvons passer à la mise à jour de notre fichier settings.py
.
Étape 3 — Mettre à jour les paramètres
Maintenant que nous avons ajouté des modèles à notre application, nous devons informer notre projet de l’existence de l’application blogsite
que nous venons d’ajouter. Nous faisons cela en l’ajoutant à la section INSTALLED_APPS
dans settings.py
.
Naviguez jusqu’au répertoire où se trouve votre fichier settings.py
.
- cd ~/my_blog_app/blog/blog
À partir de là, ouvrez votre fichier settings.py
, avec nano par exemple.
- nano settings.py
Avec le fichier ouvert, ajoutez votre application blogsite
à la section INSTALLED_APPS
du fichier, comme indiqué ci-dessous.
# Définition de l'application
INSTALLED_APPS = [
'blogsite',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
Avec l’application blogsite
ajoutée, vous pouvez enregistrer et quitter le fichier.
À ce stade, nous sommes prêts à passer à l’application de ces modifications.
Étape 4 — Effectuer les migrations
Avec nos modèles Post
et Comment
ajoutés, la prochaine étape consiste à appliquer ces modifications afin que notre schéma de base de données MySQL
les reconnaisse et crée les tables nécessaires.
Tout d’abord, nous devons regrouper nos modifications de modèle en fichiers de migration individuels à l’aide de la commande makemigrations
. Ces fichiers sont similaires à ceux des commits
dans un système de contrôle de version tel que Git.
Maintenant, si vous naviguez vers ~/my_blog_app/blog/blogsite/migrations
et exécutez ls
, vous remarquerez qu’il n’y a qu’un fichier __init__.py
. Cela changera une fois que nous aurons ajouté les migrations.
Changez vers le répertoire du blog en utilisant cd
, comme ceci:
- cd ~/my_blog_app/blog
Ensuite, exécutez la commande makemigrations
sur manage.py
.
- python manage.py makemigrations
Vous devriez alors recevoir la sortie suivante dans votre fenêtre de terminal:
OutputMigrations for 'blogsite':
blogsite/migrations/0001_initial.py
- Create model Post
- Create model Comment
Rappelez-vous, lorsque nous avons navigué vers /~/my_blog_app/blog/blogsite/migrations
et qu’il n’y avait que le fichier __init__.py
? Si nous retournons maintenant à ce répertoire, nous remarquerons que deux éléments ont été ajoutés : __pycache__
et 0001_initial.py
. Le fichier 0001_initial.py
a été automatiquement généré lorsque vous avez exécuté makemigrations
. Un fichier similaire sera généré chaque fois que vous exécutez makemigrations
.
Exécutez less 0001_initial.py
depuis le répertoire où il se trouve si vous souhaitez lire ce que contient le fichier.
Maintenant, naviguons vers ~/my_blog_app/blog
:
- cd ~/my_blog_app/blog
Étant donné que nous avons créé un fichier de migration, nous devons appliquer les modifications décrites par ces fichiers à la base de données en utilisant la commande migrate
. Mais d’abord, vérifions quelles migrations existent actuellement en utilisant la commande showmigrations
.
- python manage.py showmigrations
Outputadmin
[X] 0001_initial
[X] 0002_logentry_remove_auto_add
[X] 0003_logentry_add_action_flag_choices
auth
[X] 0001_initial
[X] 0002_alter_permission_name_max_length
[X] 0003_alter_user_email_max_length
[X] 0004_alter_user_username_opts
[X] 0005_alter_user_last_login_null
[X] 0006_require_contenttypes_0002
[X] 0007_alter_validators_add_error_messages
[X] 0008_alter_user_username_max_length
[X] 0009_alter_user_last_name_max_length
[X] 0010_alter_group_name_max_length
[X] 0011_update_proxy_permissions
blogsite
[ ] 0001_initial
contenttypes
[X] 0001_initial
[X] 0002_remove_content_type_name
sessions
[X] 0001_initial
Vous remarquerez que toutes les migrations sont vérifiées, sauf celle pour 0001_initial
que nous venons de créer avec les modèles Post
et Comment
.
Maintenant, vérifions quelles déclarations SQL
seront exécutées une fois que nous aurons effectué les migrations, en utilisant la commande suivante. Elle prend en argument la migration et le titre de la migration :
- python manage.py sqlmigrate blogsite 0001_initial
Ci-dessous est révélée la requête SQL réelle effectuée en arrière-plan.
Output--
-- Créer le modèle Post
--
CREATE TABLE `blogsite_post` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `title` varchar(255) NOT NULL, `slug` varchar(255) NOT NULL UNIQUE, `content` longtext NOT NULL, `created_on` datetime(6) NOT NULL, `author` longtext NOT NULL);
--
-- Créer le modèle Comment
--
CREATE TABLE `blogsite_comment` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(42) NOT NULL, `email` varchar(75) NOT NULL, `website` varchar(200) NULL, `content` longtext NOT NULL, `created_on` datetime(6) NOT NULL, `post_id` integer NOT NULL);
ALTER TABLE `blogsite_comment` ADD CONSTRAINT `blogsite_comment_post_id_de248bfe_fk_blogsite_post_id` FOREIGN KEY (`post_id`) REFERENCES `blogsite_post` (`id`);
Maintenant, effectuons les migrations pour qu’elles soient appliquées à notre base de données MySQL.
- python manage.py migrate
Nous recevrons la sortie suivante :
OutputOperations to perform:
Apply all migrations: admin, auth, blogsite, contenttypes, sessions
Running migrations:
Applying blogsite.0001_initial... OK
Vous avez maintenant appliqué avec succès vos migrations.
Il est important de garder à l’esprit qu’il y a trois mises en garde concernant les migrations Django avec MySQL comme backend, comme indiqué dans la documentation Django.
- Manque de support pour les transactions autour des opérations d’altération de schéma. En d’autres termes, si une migration échoue à s’appliquer avec succès, vous devrez annuler manuellement les changements que vous avez apportés afin de tenter une autre migration. Il n’est pas possible de revenir en arrière, à un point antérieur, avant que des changements aient été apportés dans la migration échouée.
- Pour la plupart des opérations d’altération de schéma, MySQL réécrira entièrement les tables. Dans le pire des cas, la complexité temporelle sera proportionnelle au nombre de lignes dans la table pour ajouter ou supprimer des colonnes. Selon la documentation Django, cela pourrait prendre jusqu’à une minute par million de lignes.
- Dans MySQL, il existe des limites de longueur pour les noms de colonnes, de tables et d’index. Il existe également une limite sur la taille combinée de toutes les colonnes et des index couverts. Alors que certains autres backends peuvent prendre en charge des limites plus élevées créées dans Django, les mêmes index échoueront à être créés avec un backend MySQL en place.
Pour chaque base de données que vous envisagez d’utiliser avec Django, assurez-vous de peser les avantages et les inconvénients de chacune.
Étape 5 — Vérification du schéma de la base de données
Avec les migrations terminées, nous devons vérifier que les tables MySQL que nous avons créées via nos modèles Django ont été générées avec succès.
Pour ce faire, exécutez la commande suivante dans le terminal pour vous connecter à MySQL. Nous utiliserons le djangouser
que nous avons créé dans le tutoriel précédent.
- mysql blog_data -u djangouser
Maintenant, sélectionnez notre base de données blog_data
. Si vous ne connaissez pas la base de données que vous utilisez, vous pouvez afficher toutes les bases de données avec SHOW DATABASES;
en SQL.
- USE blog_data;
Ensuite, saisissez la commande suivante pour voir les tables.
- SHOW TABLES;
Cette requête SQL devrait révéler ce qui suit :
Output+----------------------------+
| Tables_in_blog_data |
+----------------------------+
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| blogsite_comment |
| blogsite_post |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+----------------------------+
12 rows in set (0.01 sec)
Parmi les tables se trouvent blogsite_comment
et blogsite_post
. Ce sont les modèles que nous venons de créer. Vérifions qu’ils contiennent les champs que nous avons définis.
- DESCRIBE blogsite_comment;
Output+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(42) | NO | | NULL | |
| email | varchar(75) | NO | | NULL | |
| website | varchar(200) | YES | | NULL | |
| content | longtext | NO | | NULL | |
| created_on | datetime(6) | NO | | NULL | |
| post_id | int | NO | MUL | NULL | |
+------------+--------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)
- DESCRIBE blogsite_post;
Output+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| title | varchar(255) | NO | | NULL | |
| slug | varchar(255) | NO | UNI | NULL | |
| content | longtext | NO | | NULL | |
| created_on | datetime(6) | NO | | NULL | |
| author | longtext | NO | | NULL | |
+------------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
Nous avons vérifié que les tables de la base de données ont été générées avec succès à partir de nos migrations de modèles Django.
Vous pouvez quitter MySQL en utilisant CTRL
+ D
et lorsque vous êtes prêt à quitter votre environnement Python, vous pouvez exécuter la commande deactivate
:
- deactivate
La désactivation de votre environnement de programmation vous ramènera à l’invite de commande du terminal.
Conclusion
Dans ce tutoriel, nous avons ajouté avec succès des modèles pour les fonctionnalités de base dans une application web de blog. Vous avez appris comment coder les modèles
, comment fonctionnent les migrations
et le processus de traduction des modèles
Django en tables de base de données MySQL
réelles.
Source:
https://www.digitalocean.com/community/tutorials/how-to-create-django-models