Comment redessiner l’administration Django avec Bootstrap

Le site d’administration Django est génial — entièrement équipé, facile à utiliser, sécurisé par conception, solide comme un roc… et quelque peu laid, ce qui peut être un inconvénient quand vous souhaitez l’intégrer à l’aspect et au sentiment du reste de votre site web. Réglons cela.

Si ça n’est pas cassé…

The default Django admin. (Source)

Disons que vous venez de prototyper une application web avec Django et Vue.js. Pour un large éventail de cas, utiliser l’administration Django pour les besoins du back office telle quelle, et même la remettre à votre client après avoir appropriément défini les permissions, est tout à fait correct. Après tout, cela fonctionne parfaitement et peut être très personnalisé avec les outils intégrés pour couvrir de nombreuses situations.

Alors, pourquoi s’embêter?

Raison de modifier l’aspect et le sentiment de l’administration

Cependant, il existe de nombreuses raisons valides pour aller plus loin dans l’intégration :

  • Marquage: il n’y a rien de mal à vouloir le nom et les couleurs de votre entreprise au lieu de « Administration Django » (et pour mémoire, cela est conforme à la licence BSD de Django).
  • Intégration transparente entre le site principal et l’administration: vous pourriez souhaiter passer d’une fonctionnalité back office à la navigation sur le site, et vice versa, en ayant une barre de navigation commune.
  • Beautification: bien que l’interface d’administration soit correcte et qu’elle ait même mis en œuvre les principes de conception web responsive depuis la version 2 (elle fonctionne bien sur mobile et bureau), beaucoup peut être fait par un style CSS bien conçu pour l’améliorer.
  • Fonctionnalité de contournement: vous pourriez également simplement créer des menus déroulants personnalisés pour l’administration, affichant les options que vous utilisez réellement et cachant de l’interface utilisateur ce dont vous n’avez pas vraiment besoin, ce qui pourrait améliorer l’expérience utilisateur.

A Practical Example

Pour cet exemple, et pour ne pas nous répéter, nous reprendrons l’application web de publication simple que nous avons commencée pour l’article Prototyper une application Web avec Django et Vue.js.

En résumé:

  • a Django app with two models:
  • Article avec des champs name author (lié), content et slug
  • Author: avec des champs name et slug
  • A single view called frontend that queries all registries in both models.
  • A single template called template.
  • Mise en œuvre de Vue.js avec Vue Router et Vuex pour une interface réactive et évolutive.

Nous ne nous préoccuperons pas particulièrement de l’intégration de Vue.js dans cet épisode, et nous ne le modifierons pas ici.

Le Modèle de Base

Source

Modèles Django sont très polyvalents et puissants, et peuvent être créés au niveau de l’application (un composant du site Django) ou au niveau du site, et peuvent même remplacer les modèles fournis avec Django (ce que nous ferons ici).

Source

Nous avons créé un modèle de base qui se connecte aux JavaScript et feuille de style de Bootstrap, ainsi qu’à ses outils complémentaires, jQuery et Popper.

Voici le modèle de base que nous utilisons pour le site principal, pas du tout différent de ce que nous utiliserions normalement pour tout autre site Django :

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

    <title>Django and Vue.js</title>
  </head>
  <body class="bg-light">
    <div class="bg-white container">
      <h1>Prototyping a Web App with Django and Vue.js</h1>

      <!-- Content -->
    </div>

    <!-- Vue.js -->
    <script src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/vue-router"></script>

    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
  </body>
</html>

Ensuite, nous allons intégrer cela dans l’administration, et ajouter une barre de navigation partagée sur les deux extrémités – le site principal et le back office !

Intégration du Modèle d’Interface Utilisateur Principal avec l’Administration

Comme mentionné, nous pouvons remplacer les modèles, y compris ceux de l’administration. Cependant, en raison de la conception de Django, et sans surprise, le site principal et le back office sont deux systèmes différents, chacun avec ses propres modèles, feuilles de style et paquets contrib. Donc, même s’ils seront presque identiques, nous devrons maintenir deux modèles différents – un pour l’interface principale, et un pour l’administration.

Activation d’un Répertoire pour les Modèles en Général

Tout d’abord, nous devons indiquer à Django où nous allons stocker le modèle de l’administration modifié dans le répertoire de base.

Donc, nous devrons modifier myproject/settings.py. Tout d’abord, trouvez la constante TEMPLATES et cette clé DIRS:

'DIRS': [],

Modifiez ce code pour ceci :

'DIRS': [os.path.join(BASE_DIR, 'templates')],

Emballage du modèle d’administration (admin/base Hack)

Si nous voulions simplement apporter des modifications cosmétiques, comme passer une feuille de style personnalisée à l’administration, ou supprimer/remplacer son en-tête, nous pourrions nous en sortir en modifiant simplement le modèle admin/base_site et en sautant cette étape actuelle complètement. Cependant, si nous voulons aller jusqu’au bout et « envelopper » la section d’administration comme si elle était contenue dans notre site principal, avec la possibilité d’avoir un en-tête et un pied de page communs, alors continuez à lire.

Nous devons copier le admin/base.html de Django dans notre répertoire de modèles à templates/admin/base.html, afin que nous puissions placer nos enveloppes.

Nous allons modifier le code autour de la section container, de manière à ce qu’il passe de ceci:

<!-- Container -->
<div id="container">
(...)
</div>
<!-- END Container -->

à ceci:

{% block bodyheader %}{% endblock %}

<!-- Container -->
<div id="container">
(...)
</div>
<!-- END Container -->

{% block bodyfooter %}{% endblock %}

Et c’est tout! Nous venons simplement de créer des balises de bloc bodyheader et bodyfooter, afin que nous puissions injecter le code qui enveloppera l’administration à l’étape suivante.

Programmation d’un modèle d’administration personnalisé (admin/base_site Hack)

Alors, nous allons coder le modèle réel dans `templates/admin/base_site.html` (nous devons créer les dossiers à la racine de notre projet) :

{% extends "admin/base_site.html" %}

{% block title %}Django with Bootstrap | Admin site{% endblock %}

{% block branding %}{% endblock %}
{% block breadcrumbs %}{% endblock %}

{% block bodyclass %}bg-light{% endblock %}

{% block extrastyle %}
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    <style>
      #header, .breadcrumbs { display: none; }

      /* Problèmes Bootstrap avec l'administration */
      * { box-sizing: unset; }
      div.module caption { caption-side: top !important; }
      .collapse { display: block !important; }
    </style>
{% endblock %}

{% block bodyheader %}
    <div class="bg-white container">

      <div class="jumbotron">
        <h1 class="display-4">Hacking the Django Admin with Bootstrap</h1>
        <p class="lead">
          The <a ref="https://docs.djangoproject.com/en/dev/ref/contrib/admin/">Django administration site</a> is great—full-featured, easy to use, secure by design, rock solid… and somewhat ugly, which can be something of a downside when you want to integrate it with the look-and-feel of the rest of the website. Let’s sort that out.
        </p>
      </div>
{% endblock %}

{% block bodyfooter %}
    </div>

    <!-- jQuery en premier, puis Popper.js, puis Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
{% endblock %}

Détail

Essayons d’expliquer ce que nous faisons ici :

  1. Nous indiquons au moteur de template que nous « étendons » le modèle `admin/base_site.html`, pour remplacer efficacement certaines de ses définitions.
  2. Nous utilisons le bloc `title` pour personnaliser un titre pour la page d’administration en cours de navigation.
  3. Nous vidons le contenu des blocs `branding` et `breadcrumbs`, car nous n’en avons pas vraiment besoin.
  4. Nous utilisons le bloc `bodyclass` pour définir `bg-light` de Bootstrap, comme nous l’avons fait dans le modèle `frontend`.
  5. Nous utilisons le bloc `extrastyle` pour intégrer Bootstrap et un peu de code CSS.
    a. Bon, `#header, .breadcrumbs { display: none; }` est une sorte de répétition de la numéro 3 ; mais il est utile de savoir que vous pouvez désactiver les sections de marque et de fil d’Ariane de deux manières.
    b. Il peut y avoir des problèmes lorsque Bootstrap est superposé à la CSS de Django dans l’administration, donc ce sont quelques correctifs.
  6. Utilisez les blocs `bodyheader` et `bodyfooter` pour entourer le contenu de l’administration.

Maintenant que nous avons accès au modèle de l’administration, nous pourrions en approfondir la feuille de style, ou simplement laisser cela avec une mise en forme partagée avec l’interface principale.

Mises en garde

Nous maintenons deux modèles différents (interface principale et administration) pour présenter essentiellement la même chose. Admettons que ce n’est pas idéal, car nous violons explicitement l’un des principes fondamentaux du développement logiciel : ne vous répétez pas (DRY).

Comme nous l’avons commenté, cela est dû au fait que l’administration Django a été conçue pour être détachée de l’interface principale. Et il n’y a rien de mal à cela, tout comme il n’y a rien de mal à penser hors des sentiers battus. Mais oui, cela nous oblige à utiliser deux modèles avec à peu près le même contenu.

En réalité, en principe, nous pourrions concevoir un modèle de modèle qui comprenait cette barre de navigation et d’autres éléments communs de l’interface principale et de l’administration, et les réutiliser à partir de cette seule source ; mais à ce stade, et dans le but de cet article, cette approche serait un peu trop complexe. Quoi qu’il en soit, je vais laisser l’idée en germe pour vous. 😉

Création d’une Barre de Navigation Partagée

Maintenant que l’interface principale et le site d’administration ont l’air presque identiques, nous pouvons aller plus loin dans notre intégration et offrir une expérience de navigation commune… et même aller plus loin, présenter certaines options d’administration directement dans le menu principal !

Voici le fragment pour la barre de navigation :

<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <ul class="navbar-nav mr-auto">
    <li class="nav-item">
      <a
        class="nav-link text-primary"
        href="/author/"
      >
        Go to Authors
      </a>
    </li>
    <li class="nav-item">
      <a
        class="nav-link text-primary"
        href="/article/"
      >
        Go to Articles
      </a>
    </li>
    {% if user.is_authenticated %}
    <li class="nav-item dropdown">
      <a
        aria-expanded="false"
        aria-haspopup="true"
        class="font-weight-bold nav-link text-primary dropdown-toggle"
        data-toggle="dropdown"
        href="#"
        role="button"
      >
        Admin
      </a>
      <div class="dropdown-menu">
        <a class="dropdown-item" href="/admin/myapp/author/">
          Manage authors
        </a>
        <a class="dropdown-item" href="/admin/myapp/article/">
          Manage articles
        </a>
      </div>
    </li>
    {% endif %}
  </ul>
</nav>

Notez la section dropdown-menu, qui s’occupera de présenter un menu d’administration (voir le composant Navbar de Bootstrap pour plus d’informations).

Nous effectuons également un contrôle conditionnel avec {% if user.is_authenticated %} /{% endif %}, pour décider si nous affichons le menu d’administration ou non.

Enfin, rappelez-vous que, puisque nous maintenons maintenant deux modèles principaux différents, nous devrons ajouter le code HTML de la barre de navigation à tous les deux, myapp/templates/myapp/template.html et templates/admin/base_site.html.

Extra: l’écran de connexion Admin

Le site d’administration a été pris en charge, mais il reste un point flottant : l’écran de connexion.

Maintenant, nous pourrions transformer quelque chose comme ceci:

Source

… en quelque chose comme ceci:

Nous pouvons accomplir quelque chose de plus proche de cela en créant le modèle suivant dans templates/admin/login.html:

{% extends "admin/login.html" %}

{% load i18n static %}

{% block extrastyle %}
{{ block.super }}
<style>
#header {
  background-color: transparent !important;
}
</style>
{% endblock %}

{% block branding %}
<h1>
  <span style="color: #57C5A5 !important">ActionPlanNow.com</span>
  <br />
  <small>{% block head_title %}{% endblock %}</small>
</h1>
{% endblock %}

{% block content_title %}
<p class="lead" style="font-size: larger">
A Simple Tool for Leaders, Coaches, and Counselors.
</p>
{% endblock %}

Analyse

Ce que nous faisons ici:

  1. L’étiquette {{ block.super }} est là pour indiquer au moteur de modèles que nous ne remplaçons pas le contenu de extrastyle (que nous avons défini dans le modèle templates/admin/base_site.html) mais que nous n’ajoutons simplement du contenu à cela (voir héritage de modèles pour plus d’informations).
  2. Le bloc branding nous permet de changer l’en-tête « Administration Django » en quelque chose d’un peu plus intéressant.
  3. Nous nous débarrassons du bloc head_title en définissant une définition vide.
  4. Nous utilisons le bloc content_title pour ajouter des informations supplémentaires.

Quelques Considérations

Source

Tout comme Bootstrap, le site d’administration Django est également livré avec son propre ensemble de jQuery, mais heureusement, les développeurs Django ont pensé à cela et pour éviter les conflits avec les scripts et les bibliothèques fournis par l’utilisateur, jQuery de Django est nomméspaced en tant que django.jQuery. Nous pouvons donc inclure votre propre copie (comme nous l’avons fait) en toute sécurité.

Faites attention lorsque vous allez trop loin avec les définitions de classe dans votre feuille de style principale, car cela affectera également le site d’administration, affectant sa fonctionnalité de manière inattendue. Dans ce cas, vous pouvez toujours voir ce qui se passe avec les outils de débogage de votre navigateur, tels que Chrome DevTools, Firefox Developer Tools (en particulier Page Inspector), ou Safari Developer Tools.

Démo et Code Complet

Cette implémentation dont nous avons discuté ici ressemblera à ceci:

Vous pouvez naviguer tout le code du projet dans mon dépôt GitHub, luzdealba / djangovuejs.

Conclusion

Bien que certains pourraient affirmer — tout à fait raisonnablement — qu’il n’y a pas grand besoin de modifier l’apparence de l’administration Django, il est également vrai que intégrer de manière fluide les différents points de terminaison d’un site est une excellente astuce pour améliorer l’expérience utilisateur, car cela peut offrir une transition transparente entre les deux, et même une navigation plus contrôlée dans l’administration.

Et ce n’est pas si difficile à faire. Ce à quoi vous devez prêter attention, c’est comment vous enveloppez l’administration, et aussi comment vous mélangez les bibliothèques tierces avec votre propre code JavaScript et vos feuilles de style. Heureusement, vous pouvez très facilement intégrer certaines dans l’administration, certaines dans le reste du site principal, et certaines dans les deux.

J’espère que vous avez quelques idées sur la façon dont vous pouvez personnaliser davantage Django de manières qui n’étaient pas si évidentes!

Si vous avez besoin d’une excuse pour créer une application web juste pour jouer avec l’administration Django, consultez le tutoriel de la semaine dernière sur la création d’un prototype d’application web avec Django et Vue.js — c’est une tonne de plaisir. Et si vous souhaitez approfondir vos compétences Django, la bibliothèque SitePoint Premium dispose de nombreuses ressources à votre disposition.

Questions Fréquemment Posées (FAQs) sur la Personnalisation de l’Administration Django avec Bootstrap

Quels sont les avantages de personnaliser l’Administration Django avec Bootstrap?

Personnaliser Django Admin avec Bootstrap présente plusieurs avantages. Premièrement, cela améliore l’attrait visuel de votre interface d’administration, la rendant plus conviviale et intuitive. Bootstrap est un framework front-end populaire qui fournit une variété de modèles de conception pour la typographie, les formulaires, les boutons et d’autres composants de l’interface. En l’intégrant à Django Admin, vous pouvez exploiter ces modèles pour créer une interface d’administration plus attrayante et fonctionnelle. Deuxièmement, cela vous permet d’ajouter des fonctionnalités personnalisées à votre interface d’administration. Par exemple, vous pouvez ajouter des actions personnalisées, des filtres et des formulaires pour améliorer l’utilisabilité de votre interface d’administration. Enfin, cela peut améliorer la réactivité de votre interface d’administration, la rendant plus accessible sur différents appareils et tailles d’écran.

Comment puis-je ajouter des actions personnalisées à Django Admin?

Django Admin vous permet d’ajouter des actions personnalisées qui peuvent être effectuées sur des objets sélectionnés. Pour ajouter une action personnalisée, vous devez définir une fonction qui effectue l’action souhaitée sur les objets sélectionnés. Cette fonction doit prendre trois paramètres : l’administrateur du modèle, la requête et un queryset des objets sélectionnés. Une fois que vous avez défini cette fonction, vous pouvez l’ajouter à l’attribut ‘actions’ de votre administrateur de modèle. Cela rendra l’action disponible dans le menu déroulant des actions sur la page de liste de modification de l’administration.

Puis-je personnaliser l’apparence et la sensation de Django Admin en utilisant Bootstrap?

Oui, vous pouvez personnaliser l’apparence et la sensation de Django Admin en utilisant Bootstrap. Bootstrap est un framework front-end qui fournit une variété de modèles de conception pour la typographie, les formulaires, les boutons et d’autres composants de l’interface. En l’intégrant à Django Admin, vous pouvez tirer parti de ces modèles pour créer une interface d’administration plus attrayante et fonctionnelle. Vous pouvez personnaliser les couleurs, les polices, la mise en page et d’autres éléments de conception de votre interface d’administration pour correspondre à votre identité de marque ou à vos préférences personnelles.

Comment puis-je ajouter des filtres personnalisés à Django Admin ?

Django Admin vous permet d’ajouter des filtres personnalisés qui peuvent être utilisés pour filtrer les objets affichés sur la page de liste de modification de l’administration. Pour ajouter un filtre personnalisé, vous devez définir une sous-classe de django.contrib.admin.SimpleListFilter. Cette sous-classe doit définir deux méthodes : lookups et queryset. La méthode lookups doit renvoyer une liste de tuples, chacun représentant une option de filtre. La méthode queryset doit renvoyer un ensemble de requêtes filtrées en fonction de l’option de filtre sélectionnée. Une fois que vous avez défini cette sous-classe, vous pouvez l’ajouter à l’attribut ‘list_filter’ de votre administrateur de modèle.

Puis-je utiliser Bootstrap avec Django Admin sans aucun package supplémentaire ?

Bien qu’il soit possible d’utiliser Bootstrap avec Django Admin sans aucun package supplémentaire, il est généralement plus facile et plus efficace d’utiliser un package comme django-admin-bootstrap. Ce package fournit un thème basé sur Bootstrap pour Django Admin, ce qui facilite l’intégration de Bootstrap avec Django Admin. Il fournit également des fonctionnalités supplémentaires comme la conception responsive et le rendu de formulaires personnalisés, qui peuvent améliorer davantage l’utilisabilité et la fonctionnalité de votre interface d’administration.

Comment puis-je personnaliser les champs de formulaire dans Django Admin?

Django Admin vous permet de personnaliser les champs de formulaire utilisés pour créer ou modifier des objets. Pour personnaliser un champ de formulaire, vous devez remplacer la méthode ‘formfield_for_dbfield’ de votre administrateur de modèle. Cette méthode doit renvoyer une instance de champ de formulaire qui sera utilisée pour le champ de base de données spécifié. Vous pouvez personnaliser les attributs, les widgets et le comportement de validation du champ de formulaire pour répondre à vos besoins.

Puis-je ajouter des vues personnalisées à Django Admin?

Oui, vous pouvez ajouter des vues personnalisées à Django Admin. Pour ajouter une vue personnalisée, vous devez définir une méthode dans votre administrateur de modèle qui gère la logique de la vue. Cette méthode doit prendre une requête comme unique paramètre et renvoyer une réponse. Vous pouvez ensuite mapper cette méthode à une URL en ajoutant un modèle de URL à la méthode ‘get_urls’ de votre administrateur de modèle. Cela rendra la vue accessible à partir de l’interface d’administration.

Comment puis-je personnaliser la liste de mise en page dans Django Admin?

Django Admin vous permet de personnaliser la liste de mise en page, qui est la table d’objets affichée sur la page de liste de modification de l’admin. Pour personnaliser la liste de mise en page, vous pouvez définir l’attribut ‘list_display’ de votre administrateur de modèle sur une liste de noms de champs que vous souhaitez afficher. Vous pouvez également inclure des noms de méthodes dans cette liste, qui appellera la méthode correspondante sur chaque objet et affichera le résultat.

Puis-je utiliser Django Admin pour des modèles de base de données complexes?

Oui, Django Admin est conçu pour gérer des modèles de base de données complexes. Il offre diverses fonctionnalités qui peuvent vous aider à gérer des structures de données complexes, telles que la modification en ligne d’objets liés, des champs de formulaire personnalisés et des actions personnalisées. Cependant, pour des structures de données très complexes ou des opérations de base de données avancées, vous devrez peut-être étendre Django Admin avec des vues, formulaires ou actions personnalisés.

Comment puis-je améliorer les performances de Django Admin?

Il existe plusieurs façons d’améliorer les performances de Django Admin. Une façon est d’optimiser vos requêtes de base de données. Django Admin génère automatiquement des requêtes de base de données en fonction de vos définitions de modèles et des options d’administration. Cependant, ces requêtes peuvent parfois être inefficaces, surtout pour des structures de données complexes ou de grands ensembles de données. En personnalisant vos options d’administration et en utilisant les fonctionnalités d’optimisation de base de données de Django, vous pouvez réduire considérablement le nombre de requêtes de base de données et améliorer les performances de votre interface d’administration. Une autre façon est d’utiliser le cache. Django fournit un cadre de mise en cache robuste que vous pouvez utiliser pour mettre en cache les résultats d’opérations coûteuses ou de données fréquemment consultées. En utilisant le cache, vous pouvez réduire la charge sur votre base de données et améliorer la réactivité de votre interface d’administration.

Source:
https://www.sitepoint.com/how-to-hack-redesign-customize-the-django-admin-with-bootstrap/