Créez un journal personnel avec Django et Python
Un journal est un espace de sécurité personnel. Avec l'aide de Django, vous pouvez créer un journal sur votre propre ordinateur sans stocker de données dans le cloud de quelqu'un d'autre. En suivant le projet ci-dessous, vous verrez à quelle vitesse vous pouvez créer une application Web fonctionnelle dans Django sans aucune dépendance externe.
Dans ce didacticiel, vous apprendrez à :
- Mettre en place un projet Django
- Travailler avec la base de données SQLite standard
- Utilisez le site d'administration de Django
- Créer des modèles et des vues basées sur les classes
- Modèles d'imbrication et de style
- Sécurisez votre agenda avec authentification
Ce didacticiel vous guidera étape par étape jusqu'à votre agenda final. Si vous débutez avec Django et souhaitez terminer votre premier vrai projet, alors ce tutoriel est fait pour vous !
Pour obtenir le code source complet du projet Django et ses étapes, cliquez sur le lien ci-dessous :
Vidéo de démonstration
Sur la page principale de votre agenda, vous aurez une liste d’entrées. Vous pouvez les faire défiler et en créer de nouveaux en un seul clic. Le style est fourni dans ce tutoriel, vous pouvez donc vous concentrer sur la partie Django du code. Voici une rapide vidéo de démonstration de ce à quoi cela ressemblera en action :
À la fin du didacticiel, vous serez en mesure de naviguer parfaitement dans votre agenda pour créer, lire, mettre à jour et supprimer des entrées à la demande.
Aperçu du projet
Le didacticiel est divisé en plusieurs étapes. De cette façon, vous pourrez faire des pauses et continuer à votre rythme. À chaque étape, vous aborderez un domaine spécifique de votre projet de journal :
- Configurer votre projet de journal Django
- Création d'entrées sur le back-end
- Afficher les entrées sur le front-end
- Ajout de style
- Gestion des entrées sur le front-end
- Améliorer votre expérience utilisateur
- Implémentation de l'authentification
En suivant, vous explorerez les bases des applications Web et comment ajouter des fonctionnalités communes à un projet Django. Après avoir terminé le didacticiel, vous aurez créé votre propre application de journal personnel et disposerez d'un plan de projet Django sur lequel vous appuyer.
Conditions préalables
Vous n’avez besoin d’aucune connaissance préalable de Django pour mener à bien ce projet. Si vous souhaitez en savoir plus sur les sujets abordés dans ce didacticiel, vous trouverez des liens vers des ressources tout au long du parcours.
Cependant, vous devez être à l'aise avec la ligne de commande et avoir une connaissance de base de Python et des classes. Bien qu'il soit utile de connaître les environnements virtuels et pip
, vous apprendrez à tout configurer au cours de ce didacticiel.
Étape 1 : Configuration de votre journal Django
Démarrez le projet en créant votre répertoire de projet et en configurant un environnement virtuel. Cette configuration gardera votre code isolé de tout autre projet sur votre machine. Vous pouvez nommer votre dossier de projet et l'environnement virtuel comme vous le souhaitez. Dans ce didacticiel, le dossier du projet est nommé my-diary
et l'environnement virtuel est nommé .venv
:
$ mkdir my-diary
$ cd my-diary
$ python3 -m venv .venv
$ source .venv/bin/activate
Votre invite commence maintenant par le nom de votre environnement virtuel entre parenthèses. Ceci est un indicateur que l'environnement virtuel est activé. Pour la suite du tutoriel, votre environnement virtuel doit être activé. Toutes les étapes suivantes se dérouleront dans ce répertoire ou ses sous-répertoires.
Remarque : Pour activer votre environnement virtuel sous Windows, vous devrez peut-être exécuter cette commande :
c:\> python -m venv .venv
c:\> .venv\Scripts\activate.bat
Pour d’autres plates-formes et shells, vous devrez peut-être utiliser une commande différente.
La seule autre exigence pour votre journal est Django lui-même. Installez la version spécifique de ce tutoriel avec pip
:
(.venv) $ python -m pip install Django==3.2.1
Cette commande installe Django et certaines dépendances requises par Django. C'est tout ce dont vous avez besoin.
Initialiser Django
Une fois toutes les conditions requises remplies, il est temps de démarrer le projet Django lui-même. Utilisez l'utilitaire de ligne de commande de Django pour créer la structure de base du projet :
(.venv) $ django-admin startproject diary .
N'oubliez pas d'ajouter le point (.
) à la fin de la commande ci-dessus. Le point empêche Django de créer un autre répertoire pour votre projet de journal.
Django vient de créer un fichier manage.py
et un dossier nommé diary
avec cinq fichiers. Vous n’êtes pas obligé de comprendre ce qu’ils font précisément. Si vous êtes curieux, vous pouvez jeter un œil aux fichiers. Ils contiennent tous au début une explication décrivant pourquoi ils existent. Au cours de ce didacticiel, vous n’aurez besoin d’en modifier que deux :
manage.py
❌
diary/__init__.py
❌
diary/asgi.py
❌
diary/settings.py
✅
diary/urls.py
✅
diary/wsgi.py
-
❌
Désormais, le fichier manage.py
prendra en charge les tâches administratives en ligne de commande. Vous en rencontrerez quelques-uns au cours de ce tutoriel.
Créer la base de données
Maintenant que les bases de votre projet de journal Django sont préparées, vous avez besoin d'un emplacement pour stocker le futur contenu de votre journal. Pour cela, vous devez créer une base de données.
Django est livré avec la prise en charge de plusieurs bases de données et fonctionne par défaut avec une base de données SQLite si aucune autre configuration de base de données n'est fournie. Une base de données SQLite est tout ce dont vous avez besoin car vous êtes le seul utilisateur à s'y connecter et votre projet de journal Django ne s'exécutera que localement.
La meilleure partie est que vous pouvez créer une base de données SQLite avec une seule commande. En exécutant des migrations, vous appliquez les modifications d'un schéma de base de données dans la base de données :
(.venv) $ python manage.py migrate
Lorsque vous regardez dans le répertoire de votre projet, vous devriez voir un fichier db.sqlite3
. Donnez-vous une tape sur l'épaule : vous venez de créer une base de données !
Pour comparer l'état actuel de votre projet avec les fichiers téléchargeables pour ce didacticiel, cliquez sur le lien ci-dessous :
Les fichiers liés à cette section se trouvent dans le répertoire source_code_step_1/
.
Soyez un superutilisateur
En tant que propriétaire de votre journal personnel, vous avez mérité le rôle de superutilisateur
. Réclamez-le avec cette commande :
(.venv) $ python manage.py createsuperuser
Username (leave blank to use 'root'): admin
Email address: admin@example.com
Password: RealPyth0n
Password (again): RealPyth0n
Superuser created successfully.
Vous serez invité à choisir un nom d'utilisateur, à fournir une adresse e-mail et à définir un mot de passe. C'est la clé de votre journal, alors assurez-vous de vous en souvenir.
Exécuter un serveur Web de développement
Une autre commande que vous utiliserez fréquemment est runserver
. Cette commande exécute un serveur Web de développement léger :
(.venv) $ python manage.py runserver
Vous pouvez spécifier l'adresse IP et le port de runserver
. Par défaut, le serveur s'exécute sur le port 8000
sur 127.0.0.1
et n'est accessible que sur votre ordinateur. Avec le serveur en cours d'exécution, vous pouvez visiter votre projet Django dans votre navigateur en utilisant soit http://127.0.0.1:8000
ou http://localhost:8000
:
Ceci est la page d'accueil de votre agenda. Pour l’instant, il n’y a qu’une fusée à voir. Cela signifie que l'installation a réussi.
Important : Chaque fois que vous visitez votre projet de journal dans le navigateur, vous devez d'abord démarrer votre serveur Web de développement local s'il n'est pas déjà en cours d'exécution.
Terminez la première étape de ce didacticiel en visitant http://localhost:8000/admin
et en vous connectant avec vos informations d'identification :
Ceci est votre propre site d'administration Django ! C'est l'une des fonctionnalités les plus puissantes de Django. Avec seulement quelques ajustements, il vous donne la possibilité de gérer immédiatement le contenu et les utilisateurs. Pour l’instant, il n’y a pas grand chose à voir sur le site d’administration de Django. Il est temps de changer ça !
Étape 2 : Ajout de vos entrées de journal au back-end
Un projet Django contient une ou plusieurs applications. La portée d'une application doit être limitée. Au début, faire la différence entre un projet et des applications peut prêter à confusion. Mais dans les grands projets Django, cette séparation des préoccupations maintient la base de code propre. Un autre avantage de cette structure est que vous pouvez réutiliser des applications pour d'autres projets.
Connectez l'application Entrées
Dans votre terminal, le serveur web de développement Django est peut-être toujours en cours d'exécution. Arrêtez-le en appuyant sur Ctrl<span>+C dans le terminal.
Conseil : Ouvrez une deuxième fenêtre de terminal pour contrôler le serveur dans une fenêtre et exécuter des commandes dans l'autre :
Après avoir accédé à votre projet et activé l'environnement virtuel, vous pouvez exécuter les prochaines commandes de ce projet dans la deuxième fenêtre du terminal.
Dans ce didacticiel, vous n'avez besoin que d'une seule application supplémentaire. L'objectif principal de cette application est de gérer les entrées de votre journal, appelons donc l'application entrées
. Exécutez la commande pour créer l'application entries
:
(.venv) $ python manage.py startapp entries
Cette commande crée un dossier entries
dans votre projet avec quelques fichiers prédéfinis. Vous n’aurez besoin d’en modifier que trois plus tard dans ce didacticiel :
entries/__init__.py
❌
entries/admin.py
✅
entries/apps.py
❌
entries/models.py
✅
entries/tests.py
❌
entries/views.py
✅
Comme vous pouvez le constater, certains d'entre eux portent le même nom que les fichiers du répertoire diary/
. En cliquant sur le lien ci-dessous, vous pouvez comparer votre structure de dossiers avec celle du répertoire source_code_step_2/
:
Jusqu'à présent, Django ne connaît pas l'application que vous venez de créer. Pour connecter l'application entries
au projet de journal Django, ajoutez le chemin d'accès à la classe de configuration au début de la liste INSTALLED_APPS
dans journal/settings.py
:
# diary/settings.py
INSTALLED_APPS = [
"entries.apps.EntriesConfig",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
L'application entries
est désormais connectée au projet diary
et Django trouve ses configurations. L'une de ces configurations est le modèle qui décrit à quoi doivent ressembler vos entrées de journal dans la base de données.
Créer le modèle d'entrées
Vous avez déjà créé la base de données. Il est maintenant temps de définir la table de base de données où seront stockées les entrées de votre journal. Dans Django, vous faites cela avec une classe modèle. Tout comme les classes conventionnelles en Python, les noms de modèles doivent être au singulier et en majuscules. Alors que votre application s'appelle entries
, votre modèle s'appellera Entry
.
Les champs du modèle Entry
sont les éléments que contiendra une entrée de journal. Au premier plan, ces champs seront affichés sous forme de formulaire. Au fond, ce seront les colonnes de votre table de base de données Entry
. Une entrée de journal dans ce didacticiel contient trois champs :
titre
est le titre.content
est le corps principal du texte.date_created
est la date et l'heure de création.
Dans entries/models.py
, importez d'abord le timezone
depuis django.utils
. Créez ensuite la classe Entry
dans le même fichier comme indiqué ci-dessous :
# entries/models.py
from django.db import models
from django.utils import timezone
class Entry(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
date_created = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.title
class Meta:
verbose_name_plural = "Entries"
En important le module timezone
, vous pouvez utiliser timezone.now
comme argument default
pour date_created
à la ligne 9. De cette façon, la date et l'heure actuelles seront utilisées par défaut si vous ne leur définissez pas de valeur spécifique lors de la création d'une entrée. Vous utiliserez ce comportement plus tard lorsque vous créerez un formulaire pour vos entrées de journal.
En plus de title
, content
et date_created
, Django ajoutera automatiquement id
comme élément principal unique clé. La représentation sous forme de chaîne d'une entrée avec la clé primaire 1
serait Entry object (1)
par défaut. Lorsque vous ajoutez .__str__()
, vous pouvez personnaliser ce qui est affiché à la place. Pour une entrée de journal, le titre est une meilleure représentation sous forme de chaîne.
Une autre variable que vous devez ajuster est verbose_name_plural
. Sinon, Django épellerait le pluriel de votre Entry
comme Entrys
et non Entries
.
Enregistrez le modèle d'entrée
Pour voir également le modèle Entry
dans le site d'administration de Django, vous devez l'enregistrer dans entries/admin.py
:
# entries/admin.py
from django.contrib import admin
from .models import Entry
admin.site.register(Entry)
Django ne générera pas d'erreur lorsque vous oubliez d'enregistrer un modèle sur le site d'administration. Après tout, tous les modèles ne doivent pas nécessairement être gérés dans une interface utilisateur. Mais pour le produit minimal viable de votre agenda, vous profiterez du site d'administration Django intégré.
Migrer le modèle d'entrée
Après avoir ajouté la nouvelle classe et l'avoir enregistrée sur le site d'administration, vous devez créer des fichiers de migration pour Django et les exécuter. Avec makemigrations
, vous créez les fichiers de migration, qui contiennent les instructions de Django pour construire une base de données. Avec migrate
, vous les implémentez :
(.venv) $ python manage.py makemigrations
(.venv) $ python manage.py migrate
Une fois les migrations terminées, exécutez le serveur Web de développement, accédez au navigateur et visitez le site d'administration de Django à l'adresse http://localhost:8000/admin
:
Actuellement, aucune entrée n’est répertoriée. Terminez cette étape en créant au moins une entrée dans votre journal en cliquant sur Ajouter une entrée. Pas sûr de savoir quoi écrire? Réfléchissez peut-être à quel point il est génial d'avoir un back-end entièrement fonctionnel pour votre projet de journal Django !
Étape 3 : Affichage de vos entrées de journal sur le front-end
Vous pouvez désormais ajouter de nouvelles entrées dans le site d'administration de Django. Mais lorsque vous visitez la page d'accueil de votre journal dans le navigateur, la fusée tremblante s'affiche toujours. Dans cette étape, vous apprendrez comment afficher les entrées de votre journal sur le front-end.
Si vous souhaitez voir à quoi ressemble le code à la fin de cette étape, cliquez sur le lien ci-dessous :
Les fichiers liés à cette étape se trouvent dans le répertoire source_code_step_3/
.
Créer des vues de liste et de détail
Il existe deux types de vues dans Django : les vues basées sur les fonctions et les vues basées sur les classes. Les deux acceptent une requête Web et renvoient une réponse Web. De manière générale, les vues basées sur les fonctions vous offrent plus de contrôle mais aussi plus de travail. Les vues basées sur les classes vous offrent moins de contrôle mais aussi moins de travail.
Moins de travail, ça semble bien. Mais ce n’est pas la seule raison pour laquelle vous utiliserez des vues basées sur les classes pour votre journal. Votre journal Django utilisera des vues typiques d'une application Web, comme l'affichage d'une liste d'éléments de base de données ou de leurs détails. C’est pourquoi les vues basées sur les classes constituent un bon choix pour les vues de votre journal.
Django fournit de nombreuses vues génériques prêtes à l'emploi. Dans ce cas, vous allez créer des sous-classes d'un DetailView
et d'un ListView
et les connecter à votre modèle Entry
dans entries/views.py
:
# entries/views.py
from django.views.generic import (
ListView,
DetailView,
)
from .models import Entry
class EntryListView(ListView):
model = Entry
queryset = Entry.objects.all().order_by("-date_created")
class EntryDetailView(DetailView):
model = Entry
Comme promis, vous n’avez pas beaucoup de code à écrire pour le moment. La requête Entry.objects.all()
à la ligne 12 renverrait toutes les entrées classées par leur clé primaire. L'améliorer avec .order_by("-date_created")
renverra vos entrées par ordre croissant, avec l'entrée la plus récente en haut de la liste.
Lorsque vous écrivez une vue comme celle-ci, Django fera des hypothèses en arrière-plan, telles que le nom et l'emplacement du modèle à restituer par la vue.
Créez vos modèles
Avec les modèles, vous pouvez générer du HTML de manière dynamique. Django s'attend à ce que les modèles des vues basées sur les classes que vous venez de créer se trouvent dans un emplacement spécifique avec un nom particulier. Créez les sous-dossiers pour vos modèles :
(.venv) $ mkdir -p entries/templates/entries
Certes, le chemin vers les modèles semble un peu étrange. Mais de cette façon, vous vous assurez que Django trouvera exactement les bons modèles, même lorsque d'autres applications partagent les mêmes noms de modèles. À l'intérieur de entries/templates/entries/
, vous stockerez tous les fichiers modèles pour le modèle Entry
. Commencez par créer entry_list.html
et ajoutez ce contenu :
<!-- entries/templates/entries/entry_list.html -->
{% for entry in entry_list %}
<article>
<h2 class="{{ entry.date_created|date:'l' }}">
{{ entry.date_created|date:'Y-m-d H:i' }}
</h2>
<h3>
<a href="{% url 'entry-detail' entry.id %}">
{{ entry.title }}
</a>
</h3>
</article>
{% endfor %}
Dans les modèles Django, vous pouvez même référencer dynamiquement des classes CSS. Lorsque vous jetez un œil à <h2>
à la ligne 5, vous pouvez voir que class="{{ Entry.date_created|date:'l' }}"
est ajouté à cela. Cela montre l'horodatage avec un formatage spécial. De cette façon, l'élément <h2>
a le jour de la semaine comme classe, et vous pourrez ultérieurement attribuer à chaque jour de la semaine une couleur unique dans le CSS.
À l'intérieur de la boucle entry_list
, vous pouvez accéder aux champs du modèle Entry
. Pour ne pas encombrer la liste avec trop d'informations, vous n'afficherez le contenu que lorsque vous visiterez la page de détail d'une entrée. Créez cette page de détails dans entries/templates/entries/
avec entry_detail.html
comme nom de fichier et ajoutez ce contenu :
<!-- entries/templates/entries/entry_detail.html -->
<article>
<h2>{{ entry.date_created|date:'Y-m-d H:i' }}</h2>
<h3>{{ entry.title }}</h3>
<p>{{ entry.content }}</p>
</article>
Un modèle detail
attend exactement un objet d'entrée. C’est pourquoi vous pouvez y accéder directement ici sans boucle.
Ajouter des itinéraires à vos vues
Pour voir les modèles en action, vous devez connecter vos vues à des URL. Django fonctionne avec un fichier urls.py
pour répartir les requêtes entrantes des utilisateurs dans le navigateur. Un fichier comme celui-ci existe déjà dans le dossier du projet diary
. Pour l'application d'entrées, vous devez d'abord la créer dans entries/urls.py
et ajouter les chemins vers EntryListView
et EntryDetailView
:
# entries/urls.py
from django.urls import path
from . import views
urlpatterns = [
path(
"",
views.EntryListView.as_view(),
name="entry-list"
),
path(
"entry/<int:pk>",
views.EntryDetailView.as_view(),
name="entry-detail"
),
]
La fonction path()
aux lignes 8 et 13 doit avoir au moins deux arguments :
- Un modèle de chaîne route, qui contient un modèle d'URL
- La référence à une vue, qui est une fonction
as_view()
pour les vues basées sur les classes
De plus, vous pouvez transmettre des arguments en tant que kwargs et fournir un nom. Avec un nom, vous pouvez facilement référencer des vues dans votre projet Django. Ainsi, même si vous décidez de modifier le modèle d’URL, vous n’avez pas besoin de mettre à jour vos modèles.
Maintenant que les URL de l'application entries
sont en place, vous devez les connecter à la liste urlpatterns
de agenda
. Lorsque vous ouvrez diary/urls.py
, vous verrez les urlpatterns
utilisés par votre projet Django Diary. Jusqu'à présent, il n'y a que la route vers "admin/"
, qui est ajoutée par défaut pour que vous puissiez accéder au site d'administration de Django. Pour afficher les entrées de votre journal lorsque vous visitez http://localhost:8000
, vous devez d'abord envoyer l'URL racine à l'application entries
:
# diary/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("", include("entries.urls")),
]
Après avoir créé de nouveaux modèles, redémarrez manuellement le serveur Web de développement Django. Ensuite, visitez http://localhost:8000
et profitez de votre point de vue :
Vous pouvez voir les détails d'une entrée en cliquant sur le lien vers celle-ci dans la liste ou en visitant http://localhost:8000/entries/1
, où 1
est le ID
d'une entrée existante.
Désormais, tout est en place pour voir vos entrées en front-end. Cependant, votre journal semble toujours un peu démodé. Changeons cela à l’étape suivante !
Étape 4 : Rendre votre journal Django joli
Dans cette étape, vous ajouterez du style à votre agenda. Si vous souhaitez jeter un œil au code terminé de cette étape, cliquez sur le lien ci-dessous et consultez le répertoire source_code_step_4/
:
Bien que votre écriture soit créative, la conception du journal est actuellement un peu basique. Vous pouvez commencer à pimenter les choses en créant un modèle de base dans entries/templates/entries/base.html
avec ce contenu :
<!-- entries/templates/entries/base.html -->
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Diary</title>
<link rel="stylesheet" href="{% static 'css/diary.css' %}">
</head>
<body>
<h1><a href="/">Dear diary …</a></h1>
{% block content %}{% endblock %}
</body>
</html>
Avec l’héritage de modèles, vous n’avez pas besoin de répéter le balisage dans vos modèles. Au lieu de cela, vous étendez vos modèles enfants. Django les fusionne ensuite automatiquement lors de leur diffusion dans la vue.
Ajouter une feuille de style
En insérant {% load static %}
au début d'un fichier modèle, vous pouvez référencer des fichiers statiques avec le modèle {% static %}
balise et un chemin relatif vers le fichier CSS. Créez diary.css
dans entries/static/css/
et développez la case ci-dessous pour afficher le code CSS que vous ajouterez au fichier.
Copiez et collez le code CSS ci-dessous dans diary.css
:
/* entries/static/css/diary.css */
* {
box-sizing: border-box;
}
body {
font-family: sans-serif;
font-size: 18px;
}
a {
color: inherit;
}
a:hover {
opacity: 0.7;
}
h1 {
font-size: 2.8em;
}
h1 a {
text-decoration: none;
}
h2, h3 {
font-size: 1.4em;
margin: 0;
display: inline-block;
padding: 0.5rem 1rem;
vertical-align: top;
}
h2 {
background-color: aquamarine;
}
.mark {
background-color: gainsboro;
}
.mark a {
text-decoration: none;
}
article {
margin-bottom: 0.5rem;
}
p {
font-size: 1.2em;
padding-left: 1rem;
line-height: 1.3em;
max-width: 36rem;
color: dimgray;
}
em {
font-style: normal;
font-weight: bold;
}
/* Form */
label {
display: block;
}
button,
textarea,
input {
font-size: inherit;
min-height: 2.5em;
padding: 0 1rem;
}
input[type="text"],
textarea {
width: 100%;
}
textarea {
padding: 0.5rem 1rem;
font-family: sans-serif;
}
button,
input[type="submit"] {
margin: 0 1rem 2px 1rem;
cursor: pointer;
font-weight: bold;
min-width: 8rem;
}
/* Day coloring */
.Saturday,
.Sunday {
background-color: lightsalmon;
}
N'hésitez pas à améliorer et optimiser le code ci-dessus pour ajuster les éléments à votre goût. Si vous ne connaissez pas CSS, cela vaut la peine d’apprendre les bases si vous aimez le développement Web.
Comme indiqué précédemment, chaque élément <h2>
de la liste d'entrées a son jour de semaine en tant que classe. En stylisant différemment .Saturday
et .Sunday
, vous pouvez facilement repérer les week-ends dans la liste.
Étendre les modèles enfants
Il est maintenant temps de connecter les modèles enfants au modèle parent base.html
. Mettez à jour entries/templates/entries/entry_list.html
pour que cela ressemble à ceci :
<!-- entries/templates/entries/entry_list.html -->
{% extends "entries/base.html" %}
{% block content %}
{% for entry in entry_list %}
<article>
<h2 class="{{ entry.date_created|date:'l' }}">
{{ entry.date_created|date:'Y-m-d H:i' }}
</h2>
<h3>
<a href="{% url 'entry-detail' entry.id %}">
{{ entry.title }}
</a>
</h3>
</article>
{% endfor %}
{% endblock %}
La balise de modèle {% block %}
définit une partie du document qu'un modèle enfant peut remplacer. Pour activer cela, vous devez déclarer que votre modèle enfant étend le modèle parent et définir un élément de bloc portant le même nom. Avec la balise de modèle {% extends %}
à la ligne 3, vous définissez entries/base.html
comme parent. {% block %}
et {% endblock %}
aux lignes 5 et 18 encapsulent le balisage qui sera placé dans le bloc content
du parent.
Faites de même pour entries/templates/entries/entries_detail.html
:
<!-- entries/templates/entries/entries_detail.html -->
{% extends "entries/base.html" %}
{% block content %}
<article>
<h2>{{ entry.date_created|date:'Y-m-d H:i' }}</h2>
<h3>{{ entry.title }}</h3>
<p>{{ entry.content }}</p>
</article>
{% endblock %}
Les deux modèles héritent de la structure HTML et du style de leur modèle parent. Ils partagent le même titre et le même titre <h1>
, ainsi que le style fourni par diary.css
. Pour voir cela en action, démarrez votre serveur de développement Django et accédez à http://localhost:8000
:
Vous pouvez désormais lire vos entrées avec style. Cependant, lorsque vous souhaitez créer, mettre à jour ou supprimer une entrée, vous devez vous rendre sur le site d'administration de Django. C’est beaucoup trop de clics lorsque vous souhaitez noter rapidement quelques réflexions. Dans l'étape suivante, vous améliorerez votre flux de travail en ajoutant cette fonctionnalité au front-end.
Étape 5 : Gérer vos entrées de journal sur le front-end
Lorsque vous créez et utilisez des applications Web, vous effectuez en permanence quatre opérations de base. Ces opérations sont si courantes qu'elles sont souvent simplement désignées par l'acronyme CRUD :
- Créer
- Lire
- Mettreà jour
- Supprimer supprimer
Dans le site d'administration de Django, vous pouvez déjà effectuer toutes ces actions. Dans le front-end, vous ne pouvez lire que vos entrées jusqu'à présent. Pour ressembler aux fonctionnalités du site d'administration de Django, vous répéterez ce que vous avez déjà fait pour EntryDetail
et EntryList
, en ajoutant une vue, un modèle et une URL. .
Ajouter les vues
Dans entries/views.py
, vous avez importé ListView
et DetailView
jusqu'à présent. Mettez à jour vos instructions d'importation pour qu'elles ressemblent à ceci :
# entries/views.py
from django.urls import reverse_lazy
from django.views.generic import (
ListView,
DetailView,
CreateView,
UpdateView,
DeleteView,
)
Ajoutez vos trois sous-classes au bas de entries/views.py
:
# entries/views.py
class EntryCreateView(CreateView):
model = Entry
fields = ["title", "content"]
success_url = reverse_lazy("entry-list")
class EntryUpdateView(UpdateView):
model = Entry
fields = ["title", "content"]
def get_success_url(self):
return reverse_lazy(
"entry-detail",
kwargs={"pk": self.entry.id}
)
class EntryDeleteView(DeleteView):
model = Entry
success_url = reverse_lazy("entry-list")
Cette fois, il ne suffit pas de connecter les classes à votre modèle Entry
. Pour EntryCreateView
et EntryUpdateView
, vous devez également définir quels champs de modèle doivent être affichés dans le formulaire, comme vous pouvez le voir aux lignes 5 et 10. Votre EntryDeleteView
à la ligne 18 effectue uniquement l'action de supprimer un élément d'entrée, vous n'avez donc pas besoin d'y définir de champs.
De plus, vous devez définir où l'utilisateur doit être redirigé après avoir soumis le formulaire de vue. Par défaut, .get_success_url()
renvoie simplement la valeur de success_url
. Dans EntryUpdateView
, vous devez écraser cette méthode.
En fournissant le entry.id
comme argument de mot-clé à la ligne 15, vous restez sur la page de détail de l'entrée après l'avoir modifiée. Au lieu d'utiliser des URL, vous utilisez reverse_lazy pour y faire référence par leur nom, comme vous l'avez fait dans vos modèles.
Créer les modèles
Comme auparavant, Django recherche des modèles avec un nom spécifique :
- Pour
EntryDeleteView
, il s'agit deentry_confirm_delete.html
. - Pour
EntryCreateView
, il s'agit deentry_form.html
. - Pour
EntryUpdateView
, ce seraitentry_update_form.html
.
Lorsque Django ne trouve pas entry_update_form.html
, il essaie entry_form.html
comme solution de secours. Vous pouvez en profiter en créant un modèle qui gère les deux vues dans entries/templates/entries/
et en ajoutant un formulaire de soumission de base :
<!-- entries/templates/entries/entry_form.html -->
{% extends "entries/base.html" %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save">
</form>
{% if entry %}
<a href="{% url 'entry-detail' entry.id %}">
<button>Cancel</button>
</a>
{% else %}
<a href="{% url 'entry-list' %}">
<button>Cancel</button>
</a>
{% endif %}
{% endblock %}
Lorsque ce modèle est chargé par CreateView
, le formulaire sera vide et son annulation vous ramènera à la liste des entrées. Lorsqu'il est chargé par CreateUpdateView
, il sera prérempli avec le titre et le contenu actuels de l'entrée. L'annulation vous amènera à la page de détails de l'entrée.
Il existe plusieurs façons d'afficher un formulaire dans un modèle. Avec {{ form.as_p }}
à la ligne 7, Django affichera les champs que vous avez définis dans la vue enveloppés dans des paragraphes. Chaque fois que vous publiez du contenu dans des formulaires Django, vous devez également y inclure la balise de modèle {% csrf_token %}
à la ligne 6. Il s'agit d'une mesure de sécurité destinée à empêcher la falsification de requêtes intersites.
Comme pour les autres modèles, vous ajoutez {% extends "entries/base.html" %}
à la ligne 3 pour étendre le modèle de base. Ensuite, vous définissez ce qu'il faut inclure dans la balise block content
entre les lignes 4 et 18. Vous utilisez le même modèle pour entry_confirm_delete.html
dans entries/templates/entries/
:
<!-- entries/templates/entries/entry_confirm_delete.html -->
{% extends "entries/base.html" %}
{% block content %}
<form method="post">{% csrf_token %}
<p>
Are you sure you want to delete
<em>"{{ entry.title }}"</em>
created on {{ entry.date_created|date:'Y-m-d' }}?
</p>
<input type="submit" value="Confirm">
</form>
<a href="{% url 'entry-detail' entry.id %}">
<button>Cancel</button>
</a>
{% endblock %}
Ce modèle apparaîtra lorsque vous êtes sur le point de supprimer une entrée. Mentionner "{{ Entry.title }}"
et {{ Entry.created_date|date:'Y-m-d' }>
dans le formulaire vous rappelle quelle entrée vous supprimeriez en appuyant sur Confirmer.
Créer les URL
Après avoir créé les vues et leurs modèles, créez leurs itinéraires pour y accéder dans le front-end. Ajoutez trois chemins supplémentaires vers urlpatterns
dans entries/urls.py
:
# entries/urls.py
urlpatterns = [
path(
"",
views.EntryListView.as_view(),
name="entry-list"
),
path(
"entry/<int:pk>",
views.EntryDetailView.as_view(),
name="entry-detail"
),
path(
"create",
views.EntryCreateView.as_view(),
name="entry-create"
),
path(
"entry/<int:pk>/update",
views.EntryUpdateView.as_view(),
name="entry-update",
),
path(
"entry/<int:pk>/delete",
views.EntryDeleteView.as_view(),
name="entry-delete",
),
]
Pour entry-create
, vous n'avez besoin que d'un chemin create
de base. Comme le entry-detail
créé précédemment, entry-update
et entry-delete
ont besoin d'une clé primaire pour identifier quelle entrée doit être mise à jour ou supprimée.
Vous pouvez désormais créer, mettre à jour et supprimer des entrées pour votre agenda directement dans le front-end. Démarrez le serveur Web de développement et visitez http://localhost:8000/create
pour le tester. Si vous souhaitez comparer votre code avec celui de ce tutoriel, cliquez sur le lien ci-dessous :
Vous pouvez retrouver les fichiers liés à cette étape dans le répertoire source_code_step_5/
.
Étape 6 : Améliorer votre expérience utilisateur
En utilisant votre journal, vous êtes peut-être tombé sur quelques bizarreries qui rendent la navigation un peu ennuyeuse. Dans cette étape, vous les aborderez un par un. Vous verrez que de petits changements dans l’interface peuvent avoir un impact important sur l’expérience utilisateur de votre agenda.
Gérez votre réussite
C’est toujours agréable d’avoir des retours, surtout quand ils sont positifs. À l'aide du cadre de messages, vous pouvez définir rapidement des messages flash ponctuels qui s'affichent une fois que vous avez soumis vos formulaires. Pour utiliser cette fonctionnalité, importez les messages
et SuccessMessageMixin
dans entries/views.py
:
# entries/views.py
from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
EntryListView
et EntryDetailView
sont des vues en lecture et ne gèrent pas de formulaire. Ils peuvent afficher un message dans le modèle, mais ils n’en envoient pas. Cela signifie que vous n'avez pas besoin de sous-classer SuccessMessageMixin
pour eux. EntryCreateView
, EntryUpdateView
et EntryDeleteView
, en revanche, ajoutent une notification au stockage des messages, vous devez donc ajuster leur fonctionnalité :
# entries/views.py
class EntryCreateView(SuccessMessageMixin, CreateView):
model = Entry
fields = ["title", "content"]
success_url = reverse_lazy("entry-list")
success_message = "Your new entry was created!"
class EntryUpdateView(SuccessMessageMixin, UpdateView):
model = Entry
fields = ["title", "content"]
success_message = "Your entry was updated!"
def get_success_url(self):
return reverse_lazy(
"entry-detail",
kwargs={"pk": self.object.pk}
)
Après avoir hérité de SuccessMessageMixin
dans EntryCreateView
à la ligne 3 et dans EntryUpdateView
à la ligne 9, vous définissez un success_message
pour eux sur lignes 7 et 12. Surtout lorsque vous effectuez une action destructrice comme supprimer une entrée, il est crucial de signaler que tout s'est bien passé. Pour afficher un message dans un DeleteView
, vous devez ajouter une méthode .delete()
personnalisée et ajouter manuellement votre success_message
personnalisé au cadre de messages. :
# entries/views.py
class EntryDeleteView(DeleteView):
model = Entry
success_url = reverse_lazy("entry-list")
success_message = "Your entry was deleted!"
def delete(self, request, *args, **kwargs):
messages.success(self.request, self.success_message)
return super().delete(request, *args, **kwargs)
Vous avez besoin de cette méthode supplémentaire à la ligne 8 car la classe DeleteView
n'est pas un ancêtre d'un FormView
. C'est pourquoi vous pouvez ignorer l'ajout du SuccessMessageMixin
dans votre EntryDeleteView
à la ligne 3.
Cliquez sur le lien ci-dessous pour voir le contenu complet de entries/views.py
. Vous pouvez le trouver dans le répertoire source_code_step_6/
:
Maintenant que les vues envoient des messages, vous devez améliorer les modèles pour les afficher.
Recevoir le message
Les messages sont stockés dans le stockage des messages. En le parcourant, vous affichez tous les messages qui se trouvent actuellement dans le stockage des messages. Dans les modèles Django, vous accomplissez cela en utilisant la balise de modèle de messages. De la façon dont vous avez construit le journal et structuré les modèles, il vous suffit de l'ajouter à entries/base.html
:
<!-- entries/base.html -->
<h1><a href="/">Dear diary …</a></h1>
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li class="message">
{{ message }}
</li>
{% endfor %}
</ul>
{% endif %}
{% block content %}{% endblock %}
En enveloppant la liste des messages dans {% if messages %}
aux lignes 4 et 12, vous vous assurez qu'elle ne sera affichée que sous condition, s'il y a des messages dans le stockage.
Améliorez votre navigation
Pour créer, modifier ou supprimer une entrée, vous devez mémoriser les URL correspondantes, puis les saisir dans la barre d'adresse. Comme c'est fastidieux ! Heureusement, vous pouvez résoudre ce problème en ajoutant des liens vers les vues. Commencez par un lien vers la vue entry-create
dans le modèle entries/templates/entries/entry_list.html
:
<!-- entries/templates/entries/entry_list.html -->
{% block content %}
<article>
<h2 class="mark">{% now "Y-m-d H:i" %}</em></h2>
<a href="{% url 'entry-create' %}"><button>Add new entry</button></a>
</article>
{% for entry in entry_list %}
Ce balisage ressemblera aux autres éléments de la liste des entrées du journal. Ajoutez un nouveau paragraphe au modèle entries/templates/entries/entry_detail.html
juste après pour modifier ou supprimer rapidement une entrée :
<!-- entries/templates/entries/entry_detail.html -->
</article>
<p>
<a href="{% url 'entry-update' entry.id %}">✍️ Edit</a>
<a href="{% url 'entry-delete' entry.id %}">⛔ Delete</a>
</p>
{% endblock %}
Ce code ajoute deux liens sous les détails de l'entrée qui renvoient respectivement à entry-update
et entry-delete
.
Stylisez vos messages
Enfin, stylisez les messages flash en ajoutant .messages
et .message
à la fin de entries/static/css/diary.css
:
/* entries/static/css/diary.css */
/* Messages */
.messages {
padding: 0;
list-style: none;
}
.message {
width: 100%;
background: lightblue;
padding: 1rem;
text-align: center;
margin: 1rem 0;
}
Arrêtez le serveur Web de développement en appuyant sur Ctrl<span>+C dans le terminal et redémarrez il. Visitez ensuite http://localhost:8000
pour voir vos modifications en action. Si les messages ne semblent pas stylisés, vous devrez peut-être vider le cache de votre navigateur pour qu'il recharge les modifications de la feuille de style :
Vous possédez désormais une application Web de journal entièrement utilisable, entièrement construite dans Django. Bien que votre agenda ne soit stocké que localement, c'est une bonne idée de vous assurer que vous seul pouvez y accéder. Ajoutons cette restriction avant de commencer la journalisation.
Étape 7 : Verrouiller votre journal Django
Ce qu'un petit cadenas doré est pour un agenda physique, un formulaire de connexion l'est pour votre agenda numérique. La clé de ce verrou est la combinaison nom et mot de passe que vous utilisez déjà pour vous connecter au site d'administration de Django.
Réutilisez votre connexion administrateur Django
Le système d'authentification fourni par Django est assez basique. Pour d'autres projets avec des utilisateurs réguliers, vous pouvez envisager de le personnaliser. Mais pour votre agenda Django, il suffit de réutiliser le login du site d'administration de Django. Vous verrez que cela fonctionne très bien dans un instant. Tout d’abord, prenons soin de nous déconnecter.
Ajouter un lien de déconnexion
Vous vous déconnectez en visitant une URL spéciale. Django fournit déjà une URL avec le nom admin:logout
pour vous déconnecter du site d'administration de Django. Lorsque vous êtes connecté et que vous visitez cette URL depuis n'importe où dans votre projet, Django vous déconnecte automatiquement. Pour accéder rapidement à cette URL, ajoutez-y un lien au bas de entries/templates/entries/base.html
:
<!-- entries/templates/entries/base.html -->
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Diary</title>
<link rel="stylesheet" href="{% static 'css/diary.css' %}">
</head>
<body>
<h1><a href="/">Dear diary …</a></h1>
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li class="message">
{{ message }}
</li>
{% endfor %}
</ul>
{% endif %}
{% block content %}{% endblock %}
<hr>
<a href="{% url 'admin:logout' %}">Logout</a>
</body>
</html>
Démarrez votre serveur Web de développement, accédez à votre page d'accueil à l'adresse http://localhost:8000
et cliquez sur le lien Déconnexion. Désormais, lorsque vous visitez http://localhost:8000/admin
, vous voyez le formulaire de connexion. Cela signifie que vous êtes déconnecté. Lorsque vous visitez à nouveau http://localhost:8000
, les entrées de votre journal sont toujours accessibles. Il est temps de changer ça !
Restreindre l'accès à vos vues
Dans Django, vous pouvez définir qui est autorisé à voir quelles vues. Par défaut, ils sont ouverts à tous ceux qui visitent votre site Web. Pour vous assurer que les vues nécessitent l'accès d'un utilisateur authentifié, importez LoginRequiredMixin
en haut de entries/views.py
:
# entries/views.py
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
from django.urls import reverse_lazy
from django.views.generic import (
ListView,
DetailView,
CreateView,
UpdateView,
DeleteView,
)
from .models import Entry
Une fois qu'une classe de vue utilise LoginRequiredMixin
, elle nécessite d'abord une connexion réussie. De plus, vous devez définir une login_url
pour que Django sache où vous rediriger lorsque vous n'êtes pas connecté. Au lieu de faire cela pour toutes les classes individuellement, vous pouvez créer une classe de base qui hérite de LoginRequiredMixin
et définit le login_url
dans entries/views.py
:
# entries/views.py
class LockedView(LoginRequiredMixin):
login_url = "admin:login"
Vous pouvez désormais hériter de LockedView
dans toutes vos autres vues qui ne devraient être accessibles qu'aux utilisateurs authentifiés. Modifiez entries/views.py
pour que vos classes ressemblent à ceci :
# entries/views.py
class EntryListView(LockedView, ListView):
model = Entry
queryset = Entry.objects.all().order_by("-created_date")
class EntryDetailView(LockedView, DetailView):
model = Entry
class EntryCreateView(LockedView, SuccessMessageMixin, CreateView):
model = Entry
fields = ["title", "content"]
success_url = reverse_lazy("entry-list")
success_message = "Your new entry was created!"
class EntryUpdateView(LockedView, SuccessMessageMixin, UpdateView):
model = Entry
fields = ["title", "content"]
success_message = "Your entry was updated!"
def get_success_url(self):
return reverse_lazy("entry-detail", kwargs={"pk": self.object.pk})
class EntryDeleteView(LockedView, SuccessMessageMixin, DeleteView):
model = Entry
success_url = reverse_lazy("entry-list")
success_message = "Your entry was deleted!"
def delete(self, request, *args, **kwargs):
messages.success(self.request, self.success_message)
return super().delete(request, *args, **kwargs)
Désormais, lorsque vous visitez http://localhost:8000
, vous serez redirigé vers le formulaire de connexion Django. Une fois connecté, vous serez redirigé vers la liste des entrées et verrez tout ce qui n’est que pour vos yeux :
Et c'est tout! Vous avez réussi à créer votre propre journal personnel dans Django. Si vous souhaitez comparer votre code avec le code final du projet, alors cliquez sur le lien ci-dessous :
Le code complet du projet se trouve dans le répertoire source_code_step_final/
.
Prochaines étapes
Le journal que vous avez créé est entièrement fonctionnel et prêt à l’emploi. Mais c’est aussi une excellente base sur laquelle s’appuyer. Peut-être avez-vous déjà des idées sur la manière d’améliorer encore davantage votre agenda. Ou vous pouvez essayer l’une des idées ci-dessous :
- Ajoutez une page pour vos entrées les plus récentes.
- Donnez une couleur à chaque jour de la semaine.
- Afficher la date de création dans la balise HTML
<title>
. - Créez une sélection d'emoji du jour pour une entrée.
- Paginez la liste des entrées.
Tout au long de ce didacticiel, vous avez découvert certains concepts et modèles de base fournis par Django. Espérons que cela ait suscité un certain intérêt pour approfondir ce framework Web Python. Si vous souhaitez continuer votre voyage et en savoir plus, vous pouvez consulter ces tutoriels :
- Vos premiers pas avec Django : configurer un projet Django
- Commencez avec Django Partie 1 : Créez une application de portefeuille
- Ce que vous devez savoir pour gérer les utilisateurs dans Django Admin
- Personnaliser l'administrateur Django avec Python
- Créez un blog avec Django, Vue et GraphQL
Vous pouvez appliquer les connaissances que vous avez acquises en complétant votre projet de journal à d'autres didacticiels Django et faire passer vos compétences en applications Web au niveau supérieur !
Conclusion
Dans ce didacticiel, vous avez créé un journal personnel à partir de zéro en utilisant Django. Vous avez appris à créer une application Web complète que vous pouvez utiliser au quotidien. Il tire parti des nombreux atouts de Django, notamment le site d'administration, les vues basées sur les classes, le cadre de messages et le système de modèles.
Ce projet Django est également une base parfaite pour vos futurs projets Django. Les étapes que vous avez terminées dans ce projet de journal sont fondamentalement les mêmes pour d'autres projets, comme un blog ou une application de tâches.
Dans ce didacticiel, vous avez appris à :
- Mettre en place un projet Django
- Travailler avec la base de données SQLite standard
- Utilisez le site d'administration de Django
- Créer des modèles et des vues basées sur les classes
- Modèles d'imbrication et de style
- Sécurisez votre agenda avec authentification
Vous pouvez télécharger le code source complet du journal Django en cliquant sur le lien ci-dessous :