Ce document explique certains concepts fondamentaux que les développeurs de Django ont utilisés lors de la création du système. Son objectif est d’expliquer le passé et d’orienter l’avenir.
Un objectif fondamental de la pile Django est le couplage faible et la cohésion forte. Les différentes couches du système ne doivent rien « connaître » les unes des autres à moins que cela ne soit absolument nécessaire.
Par exemple, le système de gabarit ne sait rien des requêtes Web, la couche de base de données ne sait rien à propos de l’affichage des données et le système de vue ne se soucie guère du système de gabarit qu’un programmeur utilise.
Bien que Django soit livré avec une pile complète pour plus de commodité, les pièces de la pile sont indépendantes les unes des autres autant que possible.
Les applications Django doivent utiliser le moins de code possible ; elles doivent être exemptes de code répétitif. Django devrait tirer pleinement parti des capacités dynamiques de Python, comme l’introspection.
Le but d’un système Web au 21ème siècle est de rendre rapide les aspects fastidieux du développement Web. Django devrait permettre un développement Web incroyablement rapide.
Chaque concept/portion de données distinct devrait résider en un et un seul endroit. La redondance est mauvaise. La normalisation est bonne.
Le système, dans la limite du raisonnable, doit déduire autant que possible d’aussi peu que possible.
Il s’agit d’un principe de base de Python figurant dans PEP 20, et cela signifie que Django ne devrait pas faire trop de « magie ». La magie ne devrait se produire que s’il y a une très bonne raison pour cela. La magie est intéressante uniquement quand elle crée un confort considérable inaccessible par d’autres moyens, et quand elle est appliquée d’une manière qui ne perturbe pas les développeurs qui cherchent à apprendre à utiliser la fonction.
Le système doit être cohérent à tous les niveaux. La cohérence s’applique au tout, du bas niveau (le style de codage utilisé par Python) au haut niveau (l”« expérience » d’utilisation de Django).
Les champs ne doivent pas supposer certains comportements basés uniquement sur le nom du champ. Cela nécessite trop de connaissance du système et est sujet à des erreurs. Au lieu de cela, les comportements doivent être basés sur des paramètres nommés et, dans certains cas, sur le type de champ.
Les modèles doivent encapsuler tous les aspects d’un « objet », suivant le modèle de conception Active Record de Martin Fowler.
C’est pourquoi aussi bien les données représentées par un modèle que les informations à son sujet (son nom lisible, des options comme le tri par défaut, etc.) sont définies dans la classe du modèle ; toutes les informations nécessaires pour comprendre un modèle donné doivent être stockées dans le modèle.
Les objectifs de base de l’API de base de données sont les suivants :
Les instructions SQL doivent être exécutées le moins souvent possible, et les instructions doivent être optimisées en interne.
C’est pourquoi les développeurs doivent appeler save()
explicitement, au lieu de se baser sur un enregistrement silencieux et en arrière-plan par le système.
C’est aussi pourquoi la méthode select_related()
de QuerySet
existe. C’est une optimisation facultative des performances pour le cas courant de sélection de « tout objet lié ».
L’API de base de données devrait permettre l’utilisation d’instructions riches et expressives en aussi peu de syntaxe que possible. Elle ne devrait pas compter sur l’importation d’autres modules ou objets utilitaires.
Les jointures doivent être effectuées automatiquement, en arrière-plan, le cas échéant.
Chaque objet doit être en mesure d’accéder à tous les objets liés, dans tout le système. Cet accès devrait fonctionner dans les deux sens.
L’API de base de données devrait se rendre compte qu’elle est un raccourci, mais pas nécessairement pleine et entière. Le système devrait rendre facile l’écriture du SQL sur mesure – des instructions complètes ou simplement des clauses WHERE
sur mesure en tant que paramètres personnalisés dans les appels d’API.
Les URL dans une application Django ne devraient pas être couplées au code Python sous-jacent. Lier des URL à des noms de fonctions Python est une mauvaise pratique.
Sur le même principe, le système d’URL de Django devrait permettre aux URL d’une même application d’être différentes dans des contextes différents. Par exemple, un site pourrait placer des articles sous /stories/
, tandis qu’un autre pourrait préférer /news/
.
Les URL devraient être aussi souples que possible. Toute conception d’URL imaginable devrait être possible.
Le système devrait rendre tout aussi facile (voire même plus facile) pour un développeur de concevoir de belles URL que des vilaines.
Les extensions de fichier dans les URL de pages Web devraient être évitées.
L’utilisation abusive de virgules dans les URL devrait être sévèrement punie.
Techniquement, foo.com/bar
et foo.com/bar/
sont deux URL différentes, et les robots des moteurs de recherche (et quelques outils d’analyse de trafic Web) les traitent comme des pages distinctes. Django devrait faire un effort pour « normaliser » les URL afin de ne pas semer la confusion pour les robots des moteurs de recherche.
Tel est le raisonnement derrière le réglage APPEND_SLASH
.
Nous imaginons un système de gabarit comme un outil qui contrôle la présentation et la logique liée à la présentation – et c’est tout. Le système de gabarit ne devrait pas prendre en charge une fonctionnalité qui va au-delà de cet objectif de base.
La majorité des sites Web dynamiques utilise des parties entières et communes au design du site – un en-tête, un pied de page, une barre de navigation, etc. Le système de gabarit de Django devrait faciliter le stockage de ces éléments en un lieu unique, éliminant la duplication de code.
Telle est la philosophie derrière l”héritage de gabarit.
Le système de gabarit ne doit pas être conçu de sorte qu’il ne puisse produire que du HTML. Il devrait être tout aussi bon pour la génération d’autres formats texte, ou même du texte brut.
L’utilisation d’un moteur XML pour analyser les gabarits introduit un vaste potentiel de nouvelles erreurs humaines lors de la modification des gabarits – et entraîne un niveau inacceptable de surcharge dans le traitement du gabarit.
Le système de gabarit ne doit pas être conçu de sorte que les gabarits soient nécessairement et convenablement rendus dans les éditeurs WYSIWYG tels que Dreamweaver. C’est une restriction trop importante et ne permettrait pas à la syntaxe d’être aussi agréable qu’elle le devrait. Django pré-suppose que les auteurs de gabarit sont à l’aise avec l’édition directe de HTML.
Le système de gabarit ne doit pas faire de magie avec les espaces. Si un gabarit contient des espaces, le système devrait traiter l’espace blanc comme il traite le texte : tout simplement l’afficher. Tout espace qui n’est pas dans une balise de gabarit doit être affiché.
Le but n’est pas d’inventer un langage de programmation. L’objectif est d’offrir une fonctionnalité juste assez programmatique, comme les conditions et les boucles, ce qui est essentiel pour la prise de décision liée à la présentation. Le langage de gabarit de Django (DTL) vise à éviter toute logique avancée.
Le système de gabarit de Django postule que les gabarits sont le plus souvent écrits par les concepteurs et non par les programmeurs, et ne devraient donc pas présumer de connaissances en Python.
Nativement, le système de gabarit devrait interdire l’inclusion de code malveillant – comme les commandes qui suppriment des enregistrements en base de données.
C’est une raison supplémentaire pour laquelle le système de gabarit ne permet pas d’écrire du code Python arbitraire.
Le système de gabarit devrait admettre que les experts en rédaction de gabarits souhaitent vouloir étendre sa technologie.
Telle est la philosophie derrière les balises de gabarit et les filtres personnalisés.
La rédaction d’une vue devrait être aussi simple que d’écrire une fonction Python. Les développeurs ne devraient pas avoir besoin d’instancier une classe quand une fonction suffit.
Les vues devraient avoir accès à un objet de requête : un objet qui stocke les métadonnées sur la requête actuelle. L’objet doit être transmis directement à une fonction de vue, et ce n’est pas à la fonction de vue de devoir accéder aux données de la requête depuis une variable globale. Ceci permet de tester les vues de manière légère, propre et facile en leur passant des objets de requête « artificiels ».
Une vue ne devrait pas se soucier du système de gabarit utilisé par le développeur, ni même si un système de gabarit est réellement utilisé.
GET et POST sont distincts ; les développeurs doivent explicitement utiliser l’un ou l’autre. Le système devrait faciliter la distinction entre les données GET et POST.
Les buts principaux de l”infrastructure de cache de Django sont :
Un cache devrait être aussi rapide que possible. En conséquence, tout le code écrit autour du moteur de cache se doit de se limiter au strict minimum, particulièrement pour les opérations get()
.
L’API de cache vise à fournir une interface unifiée s’appliquant aux différents moteurs de cache.
L’API de cache doit être extensible au niveau applicatif en fonction des besoins des développeurs (par exemple, voir Transformation de clé de cache).
déc. 07, 2021