Adds a bunch of modification based

on GNU/Linux Magazine HS 109.
This commit is contained in:
Fred Pauchet 2020-08-31 21:42:20 +02:00
parent a8dbfa3b8e
commit 6da434459b
2 changed files with 137 additions and 2 deletions

View File

@ -6,15 +6,21 @@ C'est faux.
L'administration est une sorte de tour de contrôle évoluée; elle se base sur le modèle de données programmé et construit dynamiquement les formulaires qui lui est associé. Elle joue avec les clés primaires, étrangères, les champs et types de champs par https://fr.wikipedia.org/wiki/Introspection[introspection].
Son problème est qu'elle présente une courbe d'apprentissage asymptotique. Il est *très* facile d'arriver rapidement à un bon résultat, au travers d'un périmètre de configuration relativement restreint. Mais quoi que vous fassiez, il y a un moment où la courbe de paramétrage sera tellement ardue que vous aurez plus facile à développer ce que vous souhaitez ajouter en utilisant les autres concepts de Django.
Son problème est qu'elle présente une courbe d'apprentissage asymptotique. Il est *très* facile d'arriver rapidement à un bon résultat, au travers d'un périmètre de configuration relativement restreint. Mais quoi que vous fassiez, il y a un moment où la courbe de paramétrage sera tellement ardue que vous aurez plus facile à développer ce que vous souhaitez ajouter en utilisant les autres concepts de Django.
Elle doit rester dans les mains d'administrateurs ou de gestionnaires, et dans leurs mains à eux uniquement: il n'est pas question de donner des droits aux utilisateurs finaux (même si c'est extrêment tentant durant les premiers tours de roues). Indépendamment de la manière dont vous allez l'utiliser et la configurer, vous finirez par devoir développer une "vraie" application, destinée aux utilisateurs classiques, et répondant à leurs besoins uniquement.
Une bonne idée consiste à développer l'administration dans un premier temps, en *gardant en tête qu'il sera nécessaire de développer des concepts spécifiques*. Dans cet objectif, l'administration est un outil exceptionel, qui permet de valider un modèle, de créer des objets rapidement et de valider les liens qui existent entre eux. C'est un excellent outil de prototypage et de preuve de concept.
Elle se base sur plusieurs couches que l'on a déjà (ou on va bientôt) aborder (suivant le sens de lecture que vous préférez):
. Le modèle et les validateurs
. Les formulaires
. Les widgets
=== Quelques conseils
. Surchargez la méthode `__str__(self)` pour chaque classe que vous aurez définie dans le modèle. Cela permettra de construire une représentation textuelle qui représentera l'instance de votre classe. Cette information sera utilisée un peu partout dans le code, et donnera une meilleure idée de ce que l'on manipule. En plus, cette méthode est également appelée lorsque l'administration historisera une action (et comme cette étape sera inaltérable, autant qu'elle soit fixée dans le début).
. Surchargez la méthode `__str__(self)` pour chaque classe que vous aurez définie dans le modèle. Cela permettra de construire une représentation textuelle pour chaque instance de votre classe. Cette information sera utilisée un peu partout dans le code, et donnera une meilleure idée de ce que l'on manipule. En plus, cette méthode est également appelée lorsque l'administration historisera une action (et comme cette étape sera inaltérable, autant qu'elle soit fixée dans le début).
. La méthode `get_absolute_url(self)` retourne l'URL à laquelle on peut accéder pour obtenir les détails d'une instance. Par exemple:
@ -48,3 +54,127 @@ https://medium.com/@hakibenita/things-you-must-know-about-django-admin-as-your-a
En gros, le problème de l'admin est que si on fait des requêtes imbriquées, on va flinguer l'application et le chargement de la page.
La solution consiste à utiliser la propriété `list_select_related` de la classe d'Admin, afin d'appliquer une jointure par défaut et
et gagner en performances.
=== admin.ModelAdmin
La classe `admin.ModelAdmin` que l'on retrouvera principalement dans le fichier `admin.py` de chaque application contiendra la définition de ce que l'on souhaite faire avec nos données dans l'administration. Cette classe (et sa partie Meta)
=== L'affichage
Comme l'interface d'administration fonctionne (en trèèèès) gros comme un CRUD auto-généré, on trouve par défaut la possibilité de :
. Créer de nouveaux éléments
. Lister les éléments existants
. Modifier des éléments existants
. Supprimer un élément en particulier.
Les affichages sont donc de deux types: en liste et par élément.
Pour les affichages en liste, le plus simple consiste à jouer sur la propriété `list_display`.
Par défaut, la première colonne va accueillir le lien vers le formulaire d'édition.
On peut donc modifier ceci, voire créer de nouveaux liens vers d'autres éléments en construisant des URLs dynamiquement.
(Insérer ici l'exemple de Medplan pour les liens vers les postgradués :-))
Voir aussi comment personnaliser le fil d'Ariane ?
=== Les filtres
. list_filter
. filter_horizontal
. filter_vertical
. date_hierarchy
=== Les permissions
On l'a dit plus haut, il vaut mieux éviter de proposer un accès à l'administration à vos utilisateurs.
Il est cependant possible de configurer des permissions spécifiques pour certains groupes, en leur autorisant certaines actions de visualisation/ajout/édition ou suppression.
Cela se joue au niveau du `ModelAdmin`, en implémentant les méthodes suivantes:
[source,python]
----
def has_add_permission(self, request):
return True
def has_delete_permission(self, request):
return True
def has_change_permission(self, request):
return True
----
On peut accéder aux informations de l'utilisateur actuellement connecté au travers de l'objet `request.user`.
.. NOTE: ajouter un ou deux screenshots :-)
=== Les relations
==== Les relations 1-n
Les relations 1-n sont implémentées au travers de formsets (que l'on a normalement déjà décrits plus haut). L'administration permet de les définir d'une manière extrêmement simple, grâce à quelques propriétés.
L'implémentation consiste tout d'abord à définir le comportement du type d'objet référencé (la relation -N), puis à inclure cette définition au niveau du type d'objet référençant (la relation 1-).
[source,python]
----
class WishInline(TabularInline):
model = Wish
class Wishlist(admin.ModelAdmin):
...
inlines = [WishInline]
...
----
Et voilà : l'administration d'une liste de souhaits (_Wishlist_) pourra directement gérer des relations multiples vers des souhaits.
==== Les auto-suggestions et auto-complétions
Parler de l'intégration de select2.
=== La présentation
Parler ici des `fieldsets` et montrer comment on peut regrouper des champs dans des groupes, ajouter un peu de javascript, ...
=== Les actions sur des sélections
Les actions permettent de partir d'une liste d'éléments, et autorisent un utilisateur à appliquer une action sur une sélection d'éléments. Par défaut, il existe déjà une action de *suppression*.
Les paramètres d'entrée sont :
. L'instance de classe
. La requête entrante
. Le queryset correspondant à la sélection.
[source,python]
----
def double_quantity(self, request, queryset):
for obj in queryset.all():
obj.field += 1
obj.save()
double_quantity.short_description = "Doubler la quantité des souhaits."
---
Et pour informer l'utilisateur de ce qui a été réalisé, on peut aussi lui passer un petit message:
[source,python]
----
if rows_updated = 0:
self.message_user(request, "Aucun élément n'a été impacté.")
else:
self.message_user(request, "{} élément(s) mis à jour".format(rows_updated))
----

View File

@ -7,3 +7,8 @@ Django utilise un modèle https://fr.wikipedia.org/wiki/Mapping_objet-relationne
L'avantage de tout ceci est que tout reste au niveau du code. Si l'on revient sur la méthodologie des douze facteurs, ce point concerne principalement la minimisation de la divergence entre les environnements d'exécution. Déployer une nouvelle instance de l'application pourra être réalisé directement à partir d'une seule et même commande, dans la mesure où *tout est embarqué au niveau du code*.
Assez de blabla, on démarre !
=== Le modèle et les validateurs
===