Il arrive parfois, lors du développement d'un projet avec Django, qu'on se retrouve à vouloir réaliser ses propres commandes d'administration ou bien modifier le comportement par défaut des commandes existantes. D'une manière simple et efficace, Django offre la possibilité aux applications d'un projet d'enregistrer leurs propres commandes qui seront utilisées plus tard pour réaliser des actions d'administration.
Les commandes personnalisées doivent être dans un module spécifique du projet : management/commands, lui-même dans le module où se trouvent les fichiers views, models, apps, etc.
Prenons l'exemple du projet appointment, qui contient l'application core, et donc où l'on veut ajouter une commande create_doctor qui crée un objet Doctor dans la base de données en demandant les informations sur le docteur.
Voici à quoi le projet doit ressembler :
├── appointment
│ ├── asgi.py
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── core
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── management
│ │ ├── commands
│ │ │ ├── create_doctor.py
│ │ │ ├── _private.py
│ │ │ └── __init__.py
│ │ └── __init__.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── db.sqlite3
└── manage.py
Dans le fichier create_doctor.py, nous allons définir ce que nous voulons que la commande create_doctor fasse. Il est important de savoir que les fichiers commençant par un underscore (_) ne seront pas pris en compte comme commande. Par exemple, _private. Django exige que le fichier de commande contienne une classe qui hérite de BaseCommand ou l’une de ses sous-classes.
Voici le contenu du fichier create_doctor.py :
from django.core.management.base import BaseCommand
from core.models import Doctor
class Command(BaseCommand):
help = "Create a new doctor"
def add_arguments(self, parser):
# Add options for name and email
parser.add_argument('--name', type=str, help='Name of the doctor')
parser.add_argument('--email', type=str, help='Email of the doctor')
def handle(self, *args, **options):
# If name and email are provided via options
name = options['name']
email = options['email']
# If any option is missing, prompt the user for input
if not name:
name = input("Name of doctor: ")
if not email:
email = input("Email of doctor: ")
# Create the doctor in the database
Doctor.objects.create(name=name, email=email)
# Output a success message
self.stdout.write(self.style.SUCCESS(f"Doctor '{name}' created successfully"))
La seule méthode obligatoire est la méthode handle, qui doit être surchargée pour implémenter la logique de la commande que nous voulons créer. Dans notre cas, nous prenons le nom et l'email du docteur soit en arguments de la commande (--name, --email) grâce à la méthode add_arguments, qui permet de spécifier les arguments de notre commande, soit en les récupérant au clavier si l'argument en question n'est pas spécifié.
Pour exécuter la commande, il suffit juste de taper :
Name of doctor: louis
Email of doctor: louis@example.com
Doctor 'louis' created successfully
Doctor 'henri' created successfully
Il arrive parfois que l'on veuille aussi modifier le fonctionnement d'une commande déjà existante. Par exemple, nous pouvons modifier la commande createsuperuser pour demander d'autres champs en plus lors de la création du superutilisateur. J'ai donc créé un autre fichier createsuperuser.py. Pour que ma commande surcharge la commande par défaut de Django, il faut mettre mon application core avant l'application qui contient la commande createsuperuser par défaut (django.contrib.auth).
Et voici le résultat de l'exécution :
python manage.py createsuperuser
Username: tiakouang
Email: djoukevin1469@gmail.com
Password: testtest
Confirm password: testtest
First name: kevin
Last name: tiakouang
Superuser 'tiakouang' created successfully
Ainsi s’achève cette article et vous avec la possibilité de voir l’exemple réaliser dans ce tutoriel dans le dépôt github en cliquant ici.