11.2 Exemple de WAD adaptatif avec Bootstrap et Django
Objectifs d'apprentissage
À la fin de cette section, vous serez capable de :
- Créer une application web Todo avec Bootstrap et Django
- Créer un projet Django
- Créer et enregistrer une application Todo
- Définir le modèle Todo
- Mettre en place les API REST de Django
- Créer l'interface utilisateur
Dans ce module, vous allez créer une application Todo simple et adaptative. Pour ce faire, vous utiliserez Bootstrap et Django. Bootstrap est un cadriciel d'application web adaptatif et à code source ouvert, et Django est un cadriciel de développement d'applications web basé sur Python. Ces deux cadriciels sont très populaires en raison de leur facilité d'utilisation.
Création d'une application web Todo avec Bootstrap et Django
L'application web Todo de cette sous-section utilise Bootstrap et Django. Les modèles CSS de Bootstrap sont utilisés pour les fonctionnalités de l'interface utilisateur. Django sert à la fois de frontal et de dorsal. Les modèles Django font partie de l'interface utilisateur pour obtenir et définir des données via des requêtes HTTP. Les requêtes entrantes sont ensuite traitées par une API construite à l'aide du Django REST Framework.
Prérequis
Pour construire l'application Todo, vous devez installer Python, PIP, Django, Django REST Framework, Bootstrap et jQuery. L'application Todo présentée dans les pages suivantes a été développée et testée avec des versions logicielles spécifiques. Pour éviter les erreurs, veuillez vous assurer d'installer les mêmes versions : Python v3.9.4, PIP v21.3.1, Django v4.0.1, Django REST Framework v3.13.1, Bootstrap v4.5.0 et jQuery v3.5.1.
Les étapes pour construire l'application Todo sont les suivantes :
- Installer et configurer un environnement de programmation local pour Python 3.
- Télécharger et installer Python 3.9.4.
- Figure 11.14 montre comment ajouter Python et son sous-dossier Scripts à vos données d'environnement de chemin (sous Windows, les mises à jour de chemin pourraient être : C:\Users\your_username\AppData\Local\Programs\Python\Python39 et C:\Users\your_username\AppData\Local\Programs\Python\Python39\Scripts).
Figure 11.14 C'est ce qui apparaît lors de l'ajout des dossiers Python et Scripts au chemin des variables d'environnement sous Windows. (Utilisé avec l'autorisation de Microsoft.)
- Créer un environnement virtuel Python (venv) :
python -m venv py394venv - Activer l'environnement virtuel :
cd py394venv
Windows:.\Scripts\activate.bat
macOS:source ./bin/activate - Installer Django dans l'environnement de programmation local :
pip install Django==4.0.1 - Installer Django REST Framework dans l'environnement de programmation local :
pip install djangorestframework==3.13.1]
Figure 11.15 montre la séquence des étapes nécessaires pour installer l'environnement Python afin de travailler avec Django et le Django REST Framework.
Création du projet Django
La première étape pour construire une application web Django est de créer un projet Django (Django project), qui est un répertoire de haut niveau utilisé pour contenir les répertoires et les fichiers nécessaires à l'exécution d'une application web Django. Pour créer un projet Django, exécutez les commandes suivantes :
$ mkdir BootstrapDjangoToDoApp
$ cd BootstrapDjangoToDoApp
$ django-admin startproject ToDoApp.
Le point à la fin de la dernière commande est très important pour s'assurer que les fichiers dépendants de Django sont générés dans le répertoire actuel. En suivant ces commandes, le répertoire BootstrapDjangoToDoApp/ sera créé et les fichiers dépendants de Django seront générés comme le montre la Figure 11.16.
Les tables de base de données intégrées de Django sont utilisées pour gérer les utilisateurs, les groupes, les migrations, etc., dans une application web. Pour générer ces tables, exécutez la commande migrate :
$ python manage.py migrate
La dernière étape pour créer un projet Django est de confirmer que la configuration a été effectuée. Pour ce faire, exécutez la commande runserver présentée ici :
$ python manage.py runserver
Pour confirmer davantage que la configuration du projet Django a été effectuée, lancez un navigateur et accédez à http://localhost:8000. La Figure 11.17 montre la page Django.
Lien vers l'apprentissage
Django est un cadriciel web Python gratuit et à code source ouvert qui peut rendre le développement web plus efficace et moins chronophage. En mettant l'accent sur la rationalisation du développement web et en facilitant le respect des délais pour les développeurs web, Django nécessite également moins de code.
Création et enregistrement de l'application Todo
Une fois le projet Django terminé et configuré avec succès, l'étape suivante consiste à créer l'application Todo et à l'enregistrer dans le projet Django. Pour ce faire, exécutez la commande suivante :
$ python manage.py startapp todo
Le répertoire todo/ sera généré sous le répertoire du projet Django, BootstrapDjangoToDoApp/. Les fichiers liés à l'application Todo seront générés comme le montre la Figure 11.18.
Ensuite, l'application Todo doit être enregistrée dans le projet Django en tant qu'application installée afin que Django puisse la reconnaître. Pour ce faire, ouvrez le fichier ToDoApp/settings.py. Recherchez la variable INSTALLED_APPS comme le montre la Figure 11.19. Ajoutez 'todo' à la liste comme indiqué. Étant donné que le Django REST Framework sera utilisé, ajoutez également 'rest_framework' à la liste.
Définir le modèle Todo
Une fois l'application web Todo enregistrée et installée, vous pourrez créer des tâches Todo, auxquelles des catégories peuvent être attribuées. L'étape suivante consiste à créer les modèles. Deux modèles seront créés pour Category et TodoList. Ouvrez le fichier todo/models.py et ajoutez le code présenté.
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
from django.utils import timezone
# Create your models here.
class Category(models.Model):
name = models.CharField(max_length=100)
class Meta:
verbose_name = ("Category")
verbose_name_plural = ("Categories")
def __str__(self):
return self.name
class TodoList(models.Model):
title = models.CharField(max_length=250)
content = models.TextField(blank=True)
created = models.DateField(default=timezone.now().strftime("%Y-%m-%d"))
due_date = models.DateField(default=timezone.now().strftime("%Y-%m-%d"))
category = models.ForeignKey(Category, default="General", on_delete=models.DO_NOTHING)
class Meta:
ordering = ["-created"] # order by most recently created
def __str__(self):
return self.title
Les classes Python Category et TodoList décrivent les propriétés des modèles pour les tables Category et TodoList, respectivement. Le modèle TodoList contient un champ ForeignKey vers le modèle Category. Chaque élément Todo sera associé à une catégorie. Après avoir créé les modèles, un fichier de migration doit être généré pour créer les tables physiques dans la base de données. Pour générer le fichier de migration, exécutez la commande suivante :
$ python manage.py makemigrations todo
Cette commande générera un fichier de migration dans todo/migrations/, qui ressemblera au code suivant.
# Generated by Django 4.0.1 on 2022-01-30 21:14
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Category',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
],
options={
'verbose_name': 'Category',
'verbose_name_plural': 'Categories',
},
),
migrations.CreateModel(
name='TodoList',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=250)),
('content', models.TextField(blank=True)),
('created', models.DateField(default='2022-01-30')),
('due_date', models.DateField(default='2022-01-30')),
('category', models.ForeignKey(default='General', on_delete=django.db.models.deletion.DO_NOTHING, to='todo.category')),
],
options={
'ordering': ['-created'],
},
),
]
L'étape suivante consiste à appliquer les modifications du fichier de migration à la base de données, ce qui est réalisé en exécutant la commande suivante :
$ python manage.py migrate
Pour cette application, Django utilise la base de données sqlite3 (db.sqlite3) par défaut. Veuillez noter que Django prend également en charge d'autres bases de données, notamment MySQL et PostgreSQL. Pour définir le modèle Todo, vous pouvez utiliser l'interface d'administration Django par défaut pour effectuer des opérations CRUD sur la base de données. Pour utiliser l'interface d'administration, ouvrez le fichier todo/admin.py et enregistrez les modèles comme indiqué dans l'extrait de code suivant.
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib import admin
from . import models
# Register your models here.
class TodoListAdmin(admin.ModelAdmin):
list_display = ("title", "created", "due_date")
class CategoryAdmin(admin.ModelAdmin):
list_display = ("name",)
admin.site.register(models.TodoList, TodoListAdmin)
admin.site.register(models.Category, CategoryAdmin)
L'étape suivante consiste à créer un compte superutilisateur qui permet d'accéder à l'interface d'administration. Pour ce faire, exécutez la commande suivante et suivez les invites pour saisir un nom d'utilisateur, une adresse e-mail et un mot de passe pour le superutilisateur.
$ python manage.py createsuperuser
Une fois cette étape terminée, redémarrez le serveur en utilisant la commande suivante :
$ python manage.py runserver
Une fois cette opération terminée, ouvrez un navigateur et accédez à http://localhost:8000/admin/. Pour accéder à l'interface d'administration, connectez-vous avec les identifiants que vous avez configurés pour le superutilisateur. Lorsque vous vous connectez à l'interface d'administration, vous devriez voir la page suivante de la Figure 11.20. Sur cette page, vous aurez la possibilité de créer, modifier et supprimer des catégories et des éléments Todo.
Mise en place des API REST de Django
Précédemment, vous avez installé le Django REST Framework, qui fournit une boîte à outils pour construire des API. Dans cette section, vous allez créer les sérialiseurs, les fonctions de vue (View) et les routeurs nécessaires pour l'API.
Création des sérialiseurs
L'étape suivante consiste à implémenter deux sérialiseurs, un pour le modèle Category et un pour le modèle TodoList. Un sérialiseur (serializer) est un outil pour contrôler les sorties de réponse et convertir des données complexes en contenu, tel que JSON. Dans le répertoire todo/, créez le fichier serializers.py et ajoutez le code présenté dans l'extrait de code suivant. Les classes de sérialiseurs héritent de serializers.ModelSerializer car cette classe crée le sérialiseur, avec des champs correspondant aux champs du modèle définis précédemment. Chaque sérialiseur spécifie le modèle avec lequel travailler et les champs à inclure dans l'objet JSON, qui sont tous les champs.
# todo/serializers.py
from rest_framework import serializers
from .models import TodoList, Category
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = "__all__"
class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = TodoList
fields = "__all__"
Création de la vue
Après avoir créé chaque sérialiseur, l'étape suivante consiste à créer une fonction de vue correspondante pour le sérialiseur Category et le sérialiseur Todo. Pour ce faire, ouvrez todo/views.py et ajoutez le code présenté dans l'extrait de code suivant. La classe viewsets, qui fournit une implémentation par défaut des opérations CRUD, est importée de rest_framework. Les classes CategoryView et TodoView fournissent un queryset de catégories et d'éléments Todo, respectivement. Elles spécifient également la serializer_class définie dans la section précédente.
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render,redirect
from rest_framework import viewsets
from .serializers import TodoSerializer, CategorySerializer
from .models import TodoList, Category
import datetime
# Create your views here.
class CategoryView(viewsets.ModelViewSet):
queryset = Category.objects.all()
serializer_class = CategorySerializer
class TodoView(viewsets.ModelViewSet):
queryset = TodoList.objects.all()
serializer_class = TodoSerializer
Création des routeurs
L'étape suivante consiste à créer les routeurs qui fournissent les chemins d'URL pour l'API. Pour ce faire, ouvrez le fichier todo/urls.py et ajoutez le code présenté dans l'extrait de code suivant :
from django.urls import path, include
#from todo import views as todo_views
from rest_framework import routers
from todo.views import *
router = routers.DefaultRouter()
router.register(r'categories', CategoryView, basename='Categories')
router.register(r'todos', TodoView, basename='Todos')
urlpatterns = [
path('', index, name="TodoList"),
path(r'api/', include(router.urls)),
]
Une fois cette étape terminée, lancez le serveur Django en utilisant la commande suivante :
$ python manage.py runserver
Pour accéder à l'API, lancez un navigateur et accédez à http://127.0.0.1:8000/api/. Comme le montre la Figure 11.21, vous devriez voir deux chemins d'API listés, un pour les catégories et un autre pour les éléments Todo.
Les éléments Todo dépendent des catégories. Pour effectuer des opérations CRUD sur la table Category, cliquez sur le chemin d'API des catégories, comme le montre la Figure 11.22.
Une fois que vous accédez à la page Liste des catégories, entrez un nom de catégorie dans le champ situé près du bas de la page et cliquez sur le bouton Post pour l'enregistrer. Vous pouvez ajouter d'autres noms de catégories. Une fois que vous avez enregistré chaque nom à l'aide du bouton Post, les catégories apparaîtront au format JSON, comme illustré à la Figure 11.23.
Pour s'assurer que les catégories peuvent être mises à jour ou supprimées si nécessaire, la clé primaire, qui est « id », doit être incluse dans le chemin d'API (par exemple, /api/categories/{id}/). Par exemple, pour mettre à jour ou supprimer la catégorie avec id=3, le chemin d'API est /api/categories/3/. Comme le montre la Figure 11.24, une fois cette catégorie affichée sur la page Instance de catégorie, le bouton DELETE est visible en haut pour supprimer la catégorie. Si la catégorie doit être mise à jour, le bouton PUT visible près du bas peut être utilisé pour les mises à jour.
Ensuite, revenez à la racine de l'API. Cliquez sur le chemin d'API des tâches Todo pour voir, comme décrit à la Figure 11.25, qu'un élément Todo possède un champ Catégorie qui apparaît comme une liste déroulante de catégories. Les opérations CRUD peuvent également être effectuées sur la table TodoList. Cela sera fait ensuite via l'interface utilisateur à l'aide de modèles.
Création de l'interface utilisateur
Pour utiliser et contrôler l'application Todo, vous devez créer une interface utilisateur (UI). Cette section décrira les étapes à suivre pour ce faire.
Installation de Bootstrap
La première étape pour créer une UI est d'installer Bootstrap, qui, en tant que cadriciel d'application web adaptatif et à code source ouvert, peut être utilisé dans des applications web comme Django pour créer des UI. Pour installer Bootstrap dans une application Django, vous avez plusieurs options. Dans ce scénario, une méthode efficace consiste à télécharger les fichiers CSS et JS de Bootstrap et à les ajouter au répertoire static/, comme le montre la Figure 11.26. Pour ce faire, créez d'abord le répertoire static/ dans le répertoire du projet Django. De plus, pour installer jQuery, téléchargez le fichier JS et ajoutez-le au répertoire static/. Enfin, ajoutez un fichier CSS personnalisé pour inclure un style individuel dans l'application web Django.
Après avoir ajouté les fichiers CSS et JS au répertoire static/, l'étape suivante consiste à ouvrir le fichier ToDoApp/settings.py, à naviguer jusqu'à la fin du fichier et à ajouter les variables de chemin présentées dans l'extrait de code suivant.
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/
STATIC_URL = 'static/'
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static')
Création de la vue
L'étape suivante consiste à créer la vue. La fonction de vue est nécessaire pour les pages de modèle, qui sont créées dans la section suivante. La fonction de vue est également nécessaire pour interagir avec la base de données afin de créer et de supprimer des éléments Todo.
Pour créer la vue, ouvrez le fichier todo/views.py et ajoutez le code présenté dans l'extrait de code suivant. Ce code prend un objet de requête HTTP. Si la méthode de requête est POST, un élément Todo est soit créé, soit supprimé, selon le bouton sur lequel on clique. Sinon, la méthode de requête est GET et les éléments Todo sont affichés à l'utilisateur.
def index(request): # index view
todos = TodoList.objects.all() # query all todos with object manager
categories = Category.objects.all() # get all categories with object manager
if request.method == "POST": # check if request method is POST
if "taskAdd" in request.POST: # check if request is to add a todo item
title = request.POST["description"] # title
date = str(request.POST["date"]) # date
category = request.POST["category_select"] # category
content = title + " -- " + date + " " + category # content
Todo = TodoList(title=title, content=content, due_date=date, category=Category.objects.get(name=category))
Todo.save() # save todo item
return redirect("/") # reload page
if "taskDelete" in request.POST: # check if request is to delete a todo
checkedlist = request.POST["checkedbox"] # checked todos to be deleted
for todo_id in checkedlist:
todo = TodoList.objects.get(id=int(todo_id)) # get todo id
todo.delete() # delete todo
return render(request, "index.html", {"todos": todos, "categories":categories})
Création des modèles
La dernière étape pour construire une application web Django est de créer des modèles, qui sont des fichiers HTML pouvant également contenir du code Python intégré. Créez un fichier nommé style.css sous le répertoire /static/css et insérez le code présenté ici dans ce fichier. Les modèles abordés dans les sections suivantes nécessitent cette feuille de style.
/* basic reset */
*,
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
/* app */
html {
font-size: 100%;
}
body {
background: #e6f9ff;
font-family: "Open Sans", sans-serif;
}
/* super basic grid structure */
.container {
width: 600px;
margin: 0 auto;
background: #ffffff;
padding: 20px 0;
-webkit-box-shadow: 0 0 2px rgba(0, 0, 0, 0.2);
box-shadow: 0 0 2px rgba(0, 0, 0, 0.2);
}
.row {
display: block;
padding: 10px;
text-align: center;
width: 100%;
clear: both;
overflow: hidden;
}
.half {
width: 50%;
float: left;
}
.content {
background: #fff;
}
/* logo */
h1 {
font-family: "Rokkitt", sans-serif;
color: #666;
text-align: center;
font-weight: 400;
margin: 0;
}
.tagline {
margin-top: -10px;
text-align: center;
padding: 5px 20px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
color: #777;
}
/* inputs */
.inputContainer {
height: 60px;
border-top: 1px solid #e5e5e5;
position: relative;
overflow: hidden;
}
.inputContainer.last {
border-bottom: 1px solid #e5e5e5;
margin-bottom: 20px;
}
.inputContainer.half.last.right {
border-left: 1px solid #efefef;
}
input[type="date"],
input[type="text"],
select {
height: 100%;
width: 100%;
padding: 0 20px;
position: absolute;
top: 0;
vertical-align: middle;
display: inline-block;
border: none;
border-radius: none;
font-size: 13px;
color: #777;
margin: 0;
font-family: "Open Sans", sans-serif;
font-weight: 600;
letter-spacing: 0.5px;
-webkit-transition: background 0.3s;
transition: background 0.3s;
}
input[type="date"] {
cursor: pointer;
}
input[type="date"]:focus,
input[type="text"]:focus,
select:focus {
outline: none;
background: #ecf0f1;
}
::-webkit-input-placeholder {
color: lightgrey;
font-weight: normal;
-webkit-transition: all 0.3s;
transition: all 0.3s;
}
::-moz-placeholder {
color: lightgrey;
font-weight: normal;
transition: all 0.3s;
}
::-ms-input-placeholder {
color: lightgrey;
font-weight: normal;
transition: all 0.3s;
}
input:-moz-placeholder {
color: lightgrey;
font-weight: normal;
transition: all 0.3s;
}
input:focus::-webkit-input-placeholder {
color: #95a5a6;
font-weight: bold;
}
input:focus::-moz-input-placeholder {
color: #95a5a6;
font-weight: bold;
}
.inputContainer label {
padding: 5px 20px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
color: #777;
display: block;
position: absolute;
}
button {
font-family: "Open Sans", sans-serif;
background: transparent;
border-radius: 2px;
border: none;
outline: none;
height: 50px;
font-size: 14px;
color: #fff;
cursor: pointer;
text-transform: uppercase;
position: relative;
-webkit-transition: all 0.3s;
transition: all 0.3s;
padding-left: 30px;
padding-right: 15px;
}
.icon {
position: absolute;
top: 30%;
left: 10px;
font-size: 20px;
}
.taskAdd {
background: #444;
padding-left: 31px;
}
.taskAdd:hover {
background: #303030;
}
.taskDelete {
background: #e74c3c;
padding-left: 30px;
}
.taskDelete:hover {
background: #c0392b;
}
/* task styles */
.taskList {
list-style: none;
padding: 0 20px;
}
.taskItem {
border-top: 1px solid #e5e5e5;
padding: 15px 0;
color: #777;
font-weight: 600;
font-size: 14px;
letter-spacing: 0.5px;
}
.taskList .taskItem:nth-child(even) {
background: #fcfcfc;
}
.taskCheckbox {
margin-right: 1em;
}
.complete-true {
text-decoration: line-through;
color: #bebebe;
}
.taskList .taskDate {
color: #95a5a6;
font-size: 10px;
font-weight: bold;
text-transform: uppercase;
display: block;
margin-left: 41px;
}
.fa-calendar {
margin-right: 10px;
font-size: 16px;
}
[class*="category-"] {
display: inline-block;
font-size: 10px;
background: #444;
vertical-align: middle;
color: #fff;
padding: 10px;
width: 75px;
text-align: center;
border-radius: 2px;
float: right;
font-weight: normal;
text-transform: uppercase;
margin-right: 20px;
}
.category- {
background: transparent;
}
.category-Personal {
background: #2980b9;
}
.category-Work {
background: #8e44ad;
}
.category-School {
background: #f39c12;
}
.category-Cleaning {
background: #16a085;
}
.category-Other {
background: #d35400;
}
footer {
text-align: center;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
color: #777;
}
footer a {
color: #f39c12;
}
/* custom checkboxes */
.taskCheckbox {
-webkit-appearance: none;
appearance: none;
-webkit-transition: all 0.3s;
transition: all 0.3s;
display: inline-block;
cursor: pointer;
width: 19px;
height: 19px;
vertical-align: middle;
}
.taskCheckbox:focus {
outline: none;
}
.taskCheckbox:before,
.taskCheckbox:checked:before {
font-family: "FontAwesome";
color: #444;
font-size: 20px;
-webkit-transition: all 0.3s;
transition: all 0.3s;
}
.taskCheckbox:before {
content: "\f096";
}
.taskCheckbox:checked:before {
content: "\f14a";
color: #16a085;
}
/* custom select menu */
.taskCategory {
-webkit-appearance: none;
appearance: none;
cursor: pointer;
padding-left: 16.5px; /*specific positioning due to difficult behavior of select element*/
background: #fff;
}
.selectArrow {
position: absolute;
z-index: 10;
top: 35%;
right: 0;
margin-right: 20px;
color: #777;
pointer-events: none;
}
.taskCategory option {
background: #fff;
border: none;
outline: none;
padding: 0 100px;
}
Le premier fichier de modèle est base.html, qui est le fichier qui inclut les liens vers Bootstrap et jQuery. Pour illustrer ces liens, un extrait du fichier base.html est présenté dans le code. La barre de navigation Bootstrap est implémentée dans ce fichier.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>TodoApp - Django</title>
{% load static %}
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="/static/css/bootstrap.min.css" />
<link
rel="stylesheet"
type="text/css"
href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
rel="stylesheet"
type="text/css"
href="{% static 'css/style.css' %}"
/>
<!-- jQuery -->
<script
type="text/javascript"
src="{% static 'js/jquery-3.5.1.min.js' %}"></script>
<!-- Popper -->
<script
type="text/javascript"
src="{% static 'js/popper.min.js' %}"></script>
<!-- Bootstrap Core JavaScript -->
<script
type="text/javascript"
src="{% static 'js/bootstrap.bundle.min.js' %}"></script>
<script
</head>
<body>
<nav class="navbar navbar-dark bg-dark justify-content-between">
<a class="navbar-brand">ToDo</a>
<form class="form-inline">
<input
class="form-control mr-sm-2"
type="search"
placeholder="Search"
aria-label="Rechercher"
/>
<button class="btn btn-outline-info my-2 my-sm-0" type="submit">
Rechercher
</button>
</form>
</nav>
<div>{% block content %} {% endblock content %}</div>
</body>
</html>
Le deuxième fichier de modèle est index.html, qui liste tous les éléments Todo existants et inclut le formulaire pour créer ou supprimer un élément Todo. Un extrait du fichier index.html est présenté dans le code suivant. Le fichier index.html étend également le modèle base.html, ce qui permet d'insérer la barre de navigation Bootstrap implémentée dans base.html dans cette page et dans toutes les pages qui l'étendent.
{% extends "./base.html" %} {% load static %} {% block content %}
<div django-app="TaskManager">
<div class="container mt-5">
<div class="content">
<h1>Liste des tâches Todo</h1>
<!--<p class="tagline">Django Todo App</p>-->
<form action="" method="post">
{% csrf_token %}
<!-- csrf token for basic security -->
<div class="inputContainer">
<input
type="text"
id="description"
class="taskName"
placeholder="What do you need to do?"
name="description"
required
/>
<label for="description">Description</label>
</div>
<div class="inputContainer half last">
<i class="fa fa-caret-down selectArrow"></emphasis>
<select id="category" class="taskCategory" name="category_select">
<option class="disabled" value="">Choisir une catégorie</option>
{% for category in categories %}
<option
class=""
value="{{ category.name }}"
name="{{ category.name }}"
>
{{ category.name }}
</option>
{% endfor %}
</select>
<label for="category">Catégorie</label>
</div>
<div class="inputContainer half last right">
<input type="date" id="dueDate" class="taskDate" name="date" />
<label for="dueDate">Date d'échéance</label>
</div>
<div class="row">
<button class="taskAdd" name="taskAdd" type="submit">
<i class="fa fa-plus icon"></emphasis>Add task
</button>
<button
class="taskDelete"
name="taskDelete"
formnovalidate=""
type="submit"
onclick="$('input#sublist').click();"
>
<i class="fa fa-trash-o icon"></emphasis>Delete Tasks
</button>
</div>
<ul class="taskList">
{% for todo in todos %}
<!-- django template lang - for loop -->
<li class="taskItem">
<input
type="checkbox"
class="taskCheckbox"
name="checkedbox"
id="{{ todo.id }}"
value="{{ todo.id }}"
/>
<label for="{{ todo.id }}"
><span class="complete-">{{ todo.title }}</span></label>
<span class="category-{{ todo.category }}"
>{{ todo.category }}</span>
>{{ todo.category }}</span
<strong class="taskDate"
><i class="fa fa-calendar"></emphasis>Created: {{todo.created}} - Due:
>{{ todo.category }}</span
{{todo.due_date}}</strong>
>{{ todo.category }}</span
</li>
{% endfor %}
</ul>
<!-- taskList -->
</form>
</div>
<!-- content -->
</div>
<!-- container -->
</div>
{% endblock %}
La première étape pour accéder à l'application web Todo Django est de redémarrer le serveur Django en utilisant la commande suivante :
$ python manage.py runserver
Ensuite, lancez un navigateur et accédez à http://localhost:8000. La page mise en évidence à la Figure 11.27 devrait apparaître.
Pour créer une liste de tâches Todo, remplissez le formulaire et cliquez sur le bouton Ajouter une tâche comme le montre la Figure 11.28.
De plus, l'élément Todo devrait également être visible dans l'API qui a été créée. Cela devrait apparaître comme décrit à la Figure 11.29.