Framework peut être traduit en français par "cadre de travail" ou "cadriciel". Il s'agit d'un ensemble de composants servant de fondation pour développer des applications. Un framework définit une architecture globale et simplifie le développement en fournissant des fonctionnalités prêtes à l'emploi.
En Python, il existe une multitude de frameworks, notamment Django, Flask ou encore FastAPI pour ce qui concerne le développement web.
Il existe des frameworks pour d'autres besoins, par exemple Qt for Python qui permet de créer des applications de bureau avec interface graphique (GUI).
Pour les besoins d'illustration de ce glossaire, nous utiliserons le framework Django comme exemple.
Quelle différence entre framework et bibliothèque ?
Contrairement à une bibliothèque, c'est le framework qui appelle votre code aux moments appropriés : on parlera d'inversion de contrôle.
-
Une bibliothèque est une collection de fonctions que vous appelez dans votre code pour effectuer certaines tâches
-
Un framework est une structure qui appelle votre code. Le framework "fournit" un cadre prédéfinis où vous définissez le comportement de l'application en fonction de la logique métier souhaitée
Les caractéristiques d'un framework
Ne pas réinventer la roue
Les frameworks fournissent des solutions à des problèmes courants du développement, évitant ainsi d'avoir à coder des fonctionnalités standards comme l'authentification, la gestion des formulaires, ou encore la connexion à la base de données, ce qui permet de gagner un temps considérable.
Par exemple, Django, un framework web, fournit des classes et fonctions pour la gestion des formulaires, le login/logout, etc.
On peut ainsi créer et authentifier un utilisateur en quelques lignes de code, sans avoir besoin de créer toute la logique de la création du mot de passe dans la base de données (qui nécessite de solides compétences en cryptographie) :
# On utilise la classe User de Django from django.contrib.auth.models import User # Et la fonction authenticate from django.contrib.auth import authenticate # On récupère un utilisateur depuis la base de données u = User.objects.get(username="john") # On change son mot de passe u.set_password("new password") u.save() # On authentifie l'utilisateur user = authenticate(username="john", password="secret") if user is not None: # L'utilisateur existe et le mot de passe est correct : il est connecté ... else: # L'authentification n'a pas réussi ...
DRY (Don't Repeat Yourself)
Les frameworks proposent des mécanismes pour centraliser le code commun et éviter les duplications. Ils encouragent le principe DRY.
Par exemple, avec Django, vous définissez vos modèles pour la base de données à un seul endroit, et le framework génère les formulaires ainsi qu'une administration :
# models.py - Définition unique du modèle class Article(models.Model): titre = models.CharField(max_length=200) contenu = models.TextField() auteur = models.CharField(max_length=100) date_creation = models.DateTimeField(auto_now_add=True) est_publie = models.BooleanField(default=False)
Je peux générer automatiquement des formulaires en fonction du modèle :
# forms.py - Formulaire généré automatiquement class ArticleForm(ModelForm): class Meta: model = Article # Réutilise la définition du modèle fields = ['titre', 'contenu', 'auteur', 'est_publie']
Et générer en une seule ligne de code un espace d'administration pour gérer le modèle :
# admin.py - Interface d'administration auto-générée admin.site.register(Article)
Architecture prédéfinie
Un framework vous impose en partie une structure et une organisation spécifiques de votre code, ce qui favorise sa maintenabilité.
Voici un exemple standard de l'architecture d'un projet Django :
mon_projet/
├── mon_projet/ # Répertoire de configuration du projet
│ ├── __init__.py
│ ├── settings.py # Paramètres du projet
│ ├── urls.py # Routes principales
│ ├── asgi.py
│ └── wsgi.py
│
├── accounts/ # Application "accounts"
│ ├── migrations/ # Migrations de base de données
│ ├── templates/ # Templates HTML spécifiques
│ ├── tests/ # Tests de l'application
│ ├── admin.py # Configuration de l'admin
│ ├── apps.py # Configuration de l'application
│ ├── forms.py # Formulaires
│ ├── models.py # Modèles de données
│ ├── urls.py # Routes de l'application
│ └── views.py # Vues et logique
│
├── store/ # Application "store"
│ ├── migrations/
│ ├── templates/
│ ├── tests/
│ ├── admin.py
│ ├── apps.py
│ ├── forms.py
│ ├── models.py
│ ├── urls.py
│ └── views.py
│
├── media/ # Fichiers téléversés
├── templates/ # Templates partagés
└── manage.py # Utilitaire de commande
Composants réutilisables
Un framework fournit des composants pour les tâches courantes, comme l'authentification et le routage des URLs, ce qui permet aux développeurs de se concentrer sur la logique métier.
Exemple de l'interface d'administration de Django
Dans l'exemple Django suivant, le fichier urls.py montre comment on peut utiliser des composants réutilisables du framework pour gérer l'authentification et le routage des URLs :
# urls.py - Composant de routage réutilisable from django.urls import path, include from django.contrib.auth import views as auth_views urlpatterns = [ # Composants d'authentification prêts à l'emploi path('login/', auth_views.LoginView.as_view(), name='login'), path('logout/', auth_views.LogoutView.as_view(), name='logout'), path('password-reset/', auth_views.PasswordResetView.as_view(), name='password_reset'), # Vos URLs métier path('articles/', include('blog.urls')), ]
Convention plutôt que configuration
La plupart des frameworks adoptent le principe de "convention over configuration" en définissant des comportements par défaut. Cela réduit le besoin de configuration tout en laissant la possibilité de personnaliser si nécessaire.
Ci-dessus, on utilise les vues LoginView, LogoutView et PasswordResetView du module auth_views pour gérer respectivement la connexion, déconnexion, et réinitialisation du mot de passe de l'utilisateur.
Ces vues, très courantes pour n'importe quelle application, sont déjà définies dans le framework : vous gagnez donc un temps précieux car toute la logique est faite pour vous.
La plupart des réglages de Django proviennent du fichier global_settings.py du code source (il ne faut donc pas y toucher !). En revanche, le fichier settings.py est disponible dans tout projet Django et permet de modifier ou de redéfinir certaines valeurs sans vous soucier des autres.
Voici un extrait de code du fichier settings.py de Django :
# settings.py (extrait) # Par défaut, Django ajoute automatiquement un slash (/) à la fin des URLs qui n'en ont pas. # Par exemple, si un utilisateur visite "/contact", Django le redirige vers "/contact/". # Cela évite d'avoir du contenu dupliqué (mauvais pour le référencement) et standardise la structure de vos URLs. APPEND_SLASH = True # Le mode DEBUG est activé par défaut, ce qui est utile en développement # pour afficher des pages d'erreur détaillées. # En production, on le passera à False. DEBUG = True # Le fuseau horaire par défaut est UTC. # Vous pouvez facilement le changer pour 'Europe/Paris' par exemple. TIME_ZONE = 'UTC'
Extensibilité et communauté
Les frameworks permettent l'ajout de fonctionnalités via des plugins ou extensions. Bien souvent, ils bénéficient d'une communauté active qui contribue à leur évolution en développant des extensions et en rédigeant des tutoriels.
En reprenant l'exemple de Django, ce framework bénéficie d'un écosystème riche avec une multitude de librairies tierces. Voici quelques exemples :
Abstraction
Les tâches complexes, telles que la communication réseau, la gestion des requêtes ou la sécurité sont encapsulées dans des interfaces simples à utiliser.
Par exemple, Django fournit un ORM simple d'utilisation pour interagir avec la base de données sans écrire de SQL :
# Récupérer tous les articles publiés articles_publies = Article.objects.filter(est_publie=True) # Créer un nouvel article nouvel_article = Article.objects.create( titre="Mon premier article", contenu="Ceci est le contenu.", auteur="Gab" ) # Mettre à jour un article article_a_modifier = Article.objects.get(id=1) article_a_modifier.titre = "Titre mis à jour" article_a_modifier.save() # Supprimer un article article_a_supprimer = Article.objects.get(id=2) article_a_supprimer.delete()
Tout comme la gestion des requêtes HTTP :
def ma_vue(request): if request.method == 'POST': # Django abstrait les détails HTTP ...
De plus, Django inclut un moteur de templates qui permet d'insérer de la logique et de formater les données dans les fichiers HTML :
<!-- template.html --> <h1>Liste des articles</h1> <ul> {# Balise "for" pour boucler sur la liste "articles_publies" #} {% for article in articles_publies %} <li> {# {{ ... }} affiche une variable, ici le titre de l'article. #} <h2>{{ article.titre }}</h2> <p> Par {{ article.auteur }} {# Le "|" applique un filtre pour formater la date. #} le {{ article.date_creation|date:"d F Y" }} </p> {# Balise "if/else" pour la logique conditionnelle. #} {% if article.contenu %} {# Le filtre "truncatewords" limite le texte à 30 mots. #} <p>{{ article.contenu|truncatewords:30 }}</p> {% else %} <p>Cet article n'a pas encore de contenu.</p> {% endif %} </li> {% endfor %} {# Fin de la boucle for #} </ul>
Le moteur de template permet d'inclure de la logique (boucles for, structures conditionnelles avec if / else) et de faire des opérations de base sur l'affichage d'un modèle (exemple ci-dessus avec truncatewords pour tronquer le texte ou date pour formater une date en texte).
Frameworks Python populaires pour le web
Dans le cas de Python pour le web, plusieurs frameworks existent, mais les 3 plus populaires restent :
-
Django : un framework web complet, particulièrement adapté aux projets complexes nécessitant une multitude de fonctionnalités (authentification, formulaires, base de données, etc.). Avec sa philosophie "batteries included", Django fournit tout ce dont vous avez besoin pour développer une application complète.
-
Flask : micro-framework flexible, offrant une approche "à la carte", où vous ajoutez uniquement les fonctionnalités dont vous avez besoin.
-
FastAPI : un framework moderne pour le développement d'APIs. Il est très apprécié pour sa génération automatique de documentation et son support natif de l'asynchrone.
Maîtriser les bases avant le framework
Avant de se lancer dans un framework, il est fortement conseillé de bien comprendre les bases du langage. Ce qui vous permettra d'apprendre plus rapidement le framework, et d'éviter de nombreux bugs.
Par exemple, Django propose des "Class-Based Views" (CBV pour les intimes), que l'on traduit par « Vues Basées sur les Classes ».
Ces dernières s'appuient sur les principes de la programmation orientée objet. Pour bien les utiliser et les personnaliser, il faut comprendre comment fonctionnent les classes. Nul besoin d'être expert, mais au moins d'avoir les bases.
from django.views.generic import ListView from .models import Article # Pour créer une liste d'articles, on hérite de la classe ListView class ArticleListView(ListView): # On doit connaître le concept d'attribut de classe pour spécifier le modèle model = Article # Pour personnaliser la requête, on doit savoir comment redéfinir une méthode def get_queryset(self): # On appelle la méthode de la classe parente avec super() queryset = super().get_queryset() # Et on la modifie return queryset.filter(est_publie=True)
Si vous débutez, je vous conseille de suivre notre parcours complet sur les bases de Python, ou bien même d'apprendre Python tout en validant vos compétences avec notre formation certifiante TOSA.