1. Livres & vidéos
  2. Django
  3. CRUD
Extrait - Django Concevez vos applications web professionnelles en Python : du modèle de données au déploiement
Extraits du livre
Django Concevez vos applications web professionnelles en Python : du modèle de données au déploiement Revenir à la page d'achat du livre

CRUD

Présentation de l’interface administrateur

CRUD est un rétro-acronyme :

  • Create

  • Read

  • Update

  • Delete

Il s’agit des quatre opérations de base que l’on peut faire avec chaque objet.

Incidemment, il s’agit aussi des quatre permissions qui sont automatiquement créées pour chaque modèle.

Le CRUD de Django est un outil informatique autogénéré qui permet de gérer des objets simplement.

Accessible à l’URL http://localhost:8000/admin, il propose un formulaire d’authentification.

images/EI0501_01.png

Formulaire d’authentification

Une fois cet écran passé, nous arrivons sur un écran plus large où l’on peut voir la liste des modèles regroupés par application. Cliquer sur le nom du module permet d’accéder à la liste de ses instances. La partie droite du tableau affiche également la liste des dernières actions effectuées par l’utilisateur courant, c’est-à-dire celui qui est connecté.

En effet, Django dispose d’une application admin permettant spécifiquement de gérer l’interface d’administration et il existe un modèle LogEntry qui permet de logger toutes les actions des utilisateurs via cette interface.

Nous remarquons également, en haut à droite, deux liens. Le premier permet de modifier le mot de passe, le second de se déconnecter....

Côté technique

Il est maintenant temps de faire appel à un outil particulièrement utile : la barre de débogage. La première chose que nous pourrions regarder, ce sont les requêtes SQL. Testons la liste de réponses :

images/EI0501_04.png

Vue des requêtes produites par une page

Nous voyons que la dernière requête est celle issue du manager que nous avons déjà optimisée. Nous voyons aussi que la même requête est exécutée deux fois et qu’une très légère optimisation est possible.

Cet onglet sera très important pour déterminer les optimisations à mener côté SQL et pour comprendre les implications de changements que l’on serait amené à faire sur notre code.

L’autre onglet important à introduire ici est celui concernant les gabarits. Lorsque l’on affiche une page, on utilise un gabarit (template), mais ce dernier peut en hériter d’un autre et cela peut être récursif. Il peut aussi y avoir des parties de page générées par un template, ce qui est le cas pour des éléments de formulaires ou le menu de navigation, par exemple.

Cette façon de découper le code est très pratique, mais il est nécessaire de pouvoir suivre ce qu’il se passe.

Il est aussi important de visualiser tous les gabarits...

Personnalisations simples

Avant de commencer : si, à n’importe quel moment, une modification empêche l’interface d’administration de fonctionner, c’est qu’il y a un problème. Pour le connaître, deux outils sont disponibles :

$ make logs 
$ make check  

La première commande vous montrera les logs du conteneur django et vous verrez l’erreur qui fait que le conteneur n’a pas bien redémarré.

La seconde vous permettra de lancer un conteneur qui va vérifier si tout va bien et lorsqu’il y a une incohérence entre les déclarations dans l’admin et les modèles, elles sont généralement affichées.

1. Personnaliser la vue liste

Pour visualiser le code relatif à ce chapitre : git diff v1.2.2..v1.3.0.

L’objectif ici est de se poser des questions sur ce que l’on veut. Et c’est ce que l’on va faire, progressivement.

a. Quelles colonnes dans le tableau ?

Pour changer cela dans le modèle jeu, nous pouvons créer l’attribut suivant :

    list_display = ( 
        "name", 
        "status", 
        "duration", 
        "level", 
    )  

Pour le modèle utilisateur :

    list_display = ( 
        "user_username", 
        "user_first_name", 
        "user_last_name", 
        "avatar", 
        "profile_activated", 
        "subscription_date", 
        "score", 
    )  

Dans cette liste, les trois premiers éléments ne sont pas des champs. Contrairement à d’autres attributs, il n’est pas possible d’utiliser les deux caractères soulignés pour aller chercher le champ d’une clé étrangère....

Gérer des objets liés

Pour visualiser le code relatif à ce chapitre : git diff v1.3.1..v1.3.2.

1. Modifier des données d’une relation many to one

Au sein du formulaire d’un jeu, nous souhaitons pouvoir saisir les questions. Nous souhaitons voir un tableau de ces questions et que ce tableau soit modifiable. C’est ce que permettent les inlines.

class QuestionInline(admin.TabularInline): 
    model = Question 
    fields = ("text", "points", "order") 
    min_num = 2 
    max_num = 5 
    extra = 1  

Le nom des champs est assez explicite. Il faut renseigner a minima le nom du modèle concerné par l’inline et les champs que nous souhaitons voir.

Les deux champs suivants permettent de préciser le nombre minimum de lignes dans le tableau ainsi que le nombre maximal.

Le dernier champ permet de préciser le nombre de champs à laisser en plus lorsque l’on ouvre le formulaire en modification. Ainsi, s’il y a trois questions, il y aura une quatrième ligne vide, prête à saisir. S’il y a déjà cinq questions, le nombre maximal, cette ligne supplémentaire ne sera pas visible, car inutile. Cela permet d’améliorer légèrement l’expérience utilisateur....

Contrôler la visibilité

Pour visualiser le code relatif à ce chapitre : git diff v1.3.2..v1.3.3.

1. Retirer un modèle du menu

Nous souhaitons gérer les jeux et uniquement les jeux, car ce sont les entités tangibles fonctionnelles.

Les questions ne sont rien d’autre qu’une partie du jeu, et les réponses une partie des questions.

Donc, nous ne voulons pas voir apparaître les questions ou les réponses dans le menu, juste les jeux. Nous ne souhaitons pas non plus accéder à la liste des questions ou des réponses.

Pour cela, nous allons les désactiver :

@admin.register(Question) 
class QuestionAdmin(admin.ModelAdmin): 
    def has_module_permission(self, request): 
        return False 
 
 
@admin.register(Answer) 
class AnswerAdmin(admin.ModelAdmin): 
    def has_module_permission(self, request): 
        return False  

Les modèles en question doivent tout de même être déclarés et enregistrés, ils sont utilisés sous une autre forme, à partir de l’interface des jeux, via les inlines. 

Mais, la surcharge de cette méthode permet de ne plus les voir dans le menu.

2. Gérer la visibilité des interfaces

Attention ! Avec les modifications vues juste à l’instant, il est toujours possible de voir les données...

Actions

Pour visualiser le code relatif à ce chapitre : git diff v1.3.3..v1.3.4.

1. Créer une action

Une action est une tâche que l’on peut réaliser sur plusieurs objets en même temps.

Si nous allons dans la liste des jeux, nous pouvons sélectionner plusieurs jeux, puis utiliser la liste déroulante située à gauche, juste au-dessus du tableau, pour choisir une action à exécuter.

Pour l’instant, la seule action possible est de supprimer ces objets.

Si nous sommes attentifs, nous voyons qu’en cochant et décochant des lignes, le nombre d’éléments sélectionnés à droite de cette liste de sélection se met à jour.

Nous allons créer une nouvelle action pour remettre à zéro les scores de tous les joueurs sélectionnés.

Voici l’action :

    @admin.action(description=gettext("Reset scores")) 
    def reset_scores(self, request, queryset): 
        queryset.update(score=0)  

Comme nous pouvons le voir, nous avons toujours l’objet request comme paramètre, mais nous avons surtout l’objet queryset, qui représente la requête pour tous les objets sélectionnés. Nous utilisons donc simplement la méthode update pour mettre à jour...