Écriture de votre première application Django, 2ème partie

Ce tutoriel commence là où le tutoriel 1 s’achève. Nous continuons l’application de sondage Web et allons nous focaliser sur le site d’administration généré automatiquement par Django.

Philosophie

La génération de sites d’administration pour votre équipe ou vos clients pour ajouter, modifier et supprimer du contenu est un travail pénible qui ne requiert pas beaucoup de créativité. C’est pour cette raison que Django automatise entièrement la création des interfaces d’administration pour les modèles.

Django a été écrit dans un environnement éditorial, avec une très nette séparation entre les « éditeurs de contenu » et le site « public ». Les gestionnaires du site utilisent le système pour ajouter des nouvelles, des histoires, des événements, des résultats sportifs, etc., et ce contenu est affiché sur le site public. Django résout le problème de création d’une interface uniforme pour les administrateurs du site qui éditent le contenu.

L’interface d’administration n’est pas destinée à être utilisée par les visiteurs du site ; elle est conçue pour les gestionnaires du site.

Activation du site d’administration

Le site d’administration de Django n’est pas activé par défaut – c’est une fonctionnalité optionnelle. Pour l’activer dans votre installation, suivez ces trois points :

  • Décommentez "django.contrib.admin" dans le réglage INSTALLED_APPS.

  • Lancez python manage.py syncdb. Puisque vous avez ajouté une nouvelle application dans INSTALLED_APPS, les tables de la base de données ont besoin d’être mises à jour.

  • Éditez votre fichier mysite/urls.py et décommentez les lignes qui se rapportent à l’admin (il y a trois lignes à décommenter). Ce fichier est une URLconf ; nous creuserons le sujet des URLconfs dans le prochain tutoriel. Pour l’instant, tout ce que vous avez besoin de savoir est qu’il fait correspondre les racines des URL à vos applications. Vous devriez avoir finalement un fichier urls.py qui ressemble à ceci :

    from django.conf.urls import patterns, include, url
    
    # Uncomment the next two lines to enable the admin:
    from django.contrib import admin
    admin.autodiscover()
    
    urlpatterns = patterns('',
        # Examples:
        # url(r'^$', '{{ project_name }}.views.home', name='home'),
        # url(r'^{{ project_name }}/', include('{{ project_name }}.foo.urls')),
    
        # Uncomment the admin/doc line below to enable admin documentation:
        # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
    
        # Uncomment the next line to enable the admin:
        url(r'^admin/', include(admin.site.urls)),
    )
    

    (Les lignes en gras sont celles qui doivent être décommentées)

Démarrage du serveur de développement

Démarrons le serveur de développement et explorons le site d’administration.

Rappel du tutoriel 1 : vous démarrez le serveur de développement comme ceci :

python manage.py runserver

À présent, ouvrez un navigateur Web et allez à l’URL « /admin/ » de votre domaine local – par exemple, http://127.0.0.1:8000/admin/. Vous devriez voir l’écran de connexion à l’interface d’administration :

Django admin login screen

Cela ne correspond pas à ce que vous voyez ?

Si à ce stade, au lieu de la page de connexion, vous obtenez une page d’erreur signalant quelque chose comme :

ImportError at /admin/
cannot import name patterns
...

il est alors probable que vous utilisez une version de Django qui ne correspond pas à la version de ce tutoriel. Consultez alors une version plus ancienne de ce tutoriel ou installez une version plus récente de Django.

Entrée dans le site d’administration

Maintenant, essayez de vous identifier (vous avez créé un compte super-utilisateur dans la première partie du tutoriel, vous vous rappelez ? Si vous n’en avez pas créé ou que vous avez oublié le mot de passe, vous pouvez en créer un nouveau). Vous devriez voir la page d’index de l’interface d’administration de Django :

Django admin index page

Vous devriez voir quelques types de contenu modifiable, y compris les groupes, les utilisateurs et les sites. Ce sont des caractéristiques du noyau que Django intègre par défaut.

Rendre l’application de sondage modifiable via l’interface d’admin

Mais où est notre application de sondage ? Elle n’est pas affichée sur la page d’index de l’interface d’administration.

Juste une chose à faire : il faut indiquer à admin que les objets Poll ont une interface d’administration. Pour ceci, créez un fichier admin.py dans votre répertoire polls, et éditez-le de la manière suivante :

from django.contrib import admin
from polls.models import Poll

admin.site.register(Poll)

Vous aurez besoin de redémarrer le serveur de développement pour voir vos modifications. Normalement, le serveur redémarre automatiquement à chaque fois que vous modifiez un fichier, mais la création d’un nouveau fichier ne déclenche pas ce redémarrage.

Exploration des fonctionnalités de l’interface d’administration

Maintenant que nous avons inscrit Poll dans l’interface d’administration, Django sait que cela doit apparaître sur la page d’index :

Django admin index page, now with polls displayed

Cliquez sur « Polls ». À présent, vous êtes sur la page « liste pour modification » des sondages. Cette page affiche tous les sondages de la base de données et vous permet d’en choisir un pour le modifier. Il y a le sondage « Quoi de neuf ? » que nous avons créé dans le premier tutoriel :

Polls change list page

Cliquez sur le sondage « Quoi de neuf ? » pour le modifier :

Editing form for poll object

À noter ici :

  • Le formulaire est généré automatiquement à partir du modèle Poll.

  • Les différents types de champs du modèle (DateTimeField, CharField) correspondent au composant graphique d’entrée HTML approprié. Chaque type de champ sait comment s’afficher dans l’interface d’administration de Django.

  • Chaque DateTimeField reçoit automatiquement des raccourcis Javascript. Les dates obtiennent un raccourci « Aujourd’hui » et un calendrier en popup, et les heures obtiennent un raccourci « Maintenant » et une popup pratique qui liste les heures couramment saisies.

La partie inférieure de la page vous propose une série d’opérations :

  • Enregistrer – Enregistre les modifications et retourne à la page liste pour modification de ce type d’objet.

  • Enregistrer et continuer les modifications – Enregistre les modifications et recharge la page d’administration de cet objet.

  • Enregistrer et ajouter un nouveau – Enregistre les modifications et charge un nouveau formulaire vierge pour ce type d’objet.

  • Supprimer – Affiche une page de confirmation de la suppression.

Si la valeur de « Date de publication » ne correspond pas à l’heure à laquelle vous avez créé ce sondage dans le tutoriel 1, vous avez probablement oublié de définir la valeur correcte du réglage TIME_ZONE. Modifiez-le, rechargez la page et vérifiez que la bonne valeur s’affiche.

Modifiez la « Date de publication » en cliquant sur les raccourcis « Aujourd’hui » et « Maintenant ». Puis cliquez sur « Enregistrer et continuer les modifications ». Ensuite, cliquez sur « Historique » en haut à droite de la page. Vous verrez une page listant toutes les modifications effectuées sur cet objet via l’interface d’administration de Django, accompagnées des date et heure, ainsi que du nom de l’utilisateur qui a fait ce changement :

History page for poll object

Personnalisation du formulaire d’administration

Prenez quelques minutes pour vous émerveiller devant le code que vous n’avez pas dû écrire. Quand vous avez inscrit le modèle Poll avec admin.site.register(Poll), Django a été capable de représenter l’objet dans un formulaire par défaut. Il sera cependant souvent souhaitable de personnaliser l’affichage et le comportement du formulaire. Cela se fait en indiquant certaines options à Django lors de l’inscription de l’objet.

Voyons comment cela fonctionne, en réordonnant les champs sur le formulaire d’édition. Remplacez la ligne admin.site.register(Poll) par :

class PollAdmin(admin.ModelAdmin):
    fields = ['pub_date', 'question']

admin.site.register(Poll, PollAdmin)

Vous suivrez cette méthode – c’est-à-dire créer un objet d’administration de modèle, puis le transmettre en tant que deuxième paramètre de admin.site.register() – à chaque fois que vous aurez besoin de modifier les options d’administration pour un objet.

Cette modification fait que la « Date de publication » apparaît avant le champ « Question » :

Fields have been reordered

Ce n’est pas spécialement impressionnant avec seulement deux champs, mais pour un formulaire d’administration avec des dizaines de champs, choisir un ordre intuitif est un détail d’utilisation important.

Et en parlant de formulaires avec des dizaines de champs, il peut être utile de partager le formulaire en plusieurs sous-ensembles (fieldsets) :

class PollAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question']}),
        ('Date information', {'fields': ['pub_date']}),
    ]

admin.site.register(Poll, PollAdmin)

Le premier élément de chaque tuple dans fieldsets est le titre du groupe de champs. Voici ce à quoi notre formulaire ressemble à présent :

Form has fieldsets now

Vous pouvez attribuer des classes HTML arbitraires à chaque sous-ensemble. Django fournit une classe "collapse" qui affiche un sous-ensemble particulier, initialement replié. C’est une fonctionnalité utile lorsque vous avez un long formulaire qui contient un certain nombre de champs qui ne sont pas couramment utilisés :

class PollAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question']}),
        ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
    ]
Fieldset is initially collapsed

Personnalisation de la liste pour modification de l’interface d’administration

Maintenant que la page d’administration des sondage « Poll » présente un peu mieux, améliorons la page « liste pour modification » – celle qui affiche tous les sondages du système.

Voici à quoi ça ressemble pour l’instant :

Polls change list page

Par défaut, Django affiche le str() de chaque objet. Mais parfois, il serait plus utile d’afficher des champs particuliers. Dans ce but, utilisez l’option list_display, qui est un tuple de noms de champs à afficher, en colonnes, sur la page liste pour modification de l’objet :

class PollAdmin(admin.ModelAdmin):
    # ...
    list_display = ('question', 'pub_date')

Juste pour la démonstration, incluons également la méthode personnalisée``was_published_today`` du tutoriel 1 :

class PollAdmin(admin.ModelAdmin):
    # ...
    list_display = ('question', 'pub_date', 'was_published_recently')

À présent, la page liste pour modification des sondages ressemble à ceci :

Polls change list page, updated

Vous pouvez cliquer sur les en-têtes de colonne pour trier selon ces valeurs – sauf dans le cas de l’en-tête was_published_today, parce que le tri selon le résultat d’une méthode arbitraire n’est pas pris en charge. Notez aussi que l’en-tête de la colonne pour was_published_today est, par défaut, le nom de la méthode (avec les soulignements remplacés par des espaces) et que chaque ligne contient la représentation textuelle du résultat.

Vous pouvez améliorer cela en fournissant à cette méthode (dans polls/models.py) quelques attributs, comme ceci :

class Poll(models.Model):
    # ...
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
    was_published_recently.admin_order_field = 'pub_date'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently?'

Modifiez encore une fois le fichier polls/admin.py et améliorez la page liste pour modification de sondages en y ajoutant des filtres. Ajoutez la ligne suivante à PollAdmin:

list_filter = ['pub_date']

Cela ajoute une barre latérale « Filter » qui permet de filtrer la liste pour modification selon le champ pub_date :

Polls change list page, updated

Le type de filtre affiché dépend du type de champ à filtrer. Comme pub_date est un champ DateTimeField, Django sait fournir des options de filtrage appropriées : « Toutes les dates », « Aujourd’hui », « Les 7 derniers jours », « Ce mois-ci », « Cette année ».

Ça a meilleure forme. Ajoutons une fonctionnalité de recherche :

search_fields = ['question']

Cela ajoute une boîte de recherche en haut de la liste pour modification. Quand quelqu’un saisit des termes de recherche, Django va rechercher dans le champ question. Vous pouvez indiquer autant de champs que vous le désirez – néanmoins, en raison de l’emploi d’une requête LIKE en arrière-plan, il ne faut pas exagérer si l’on ne veut pas se fâcher avec la base de données.

Enfin, parce que les objets Poll possèdent des dates, il serait pratique de pouvoir les sélectionner par date. Ajoutez cette ligne :

date_hierarchy = 'pub_date'

Cela ajoute une navigation hiérarchique, par date, en haut de la page liste pour modification. Au premier niveau, il affiche toutes les années disponibles. Puis il affine le classement au mois et, finalement, au jours.

C’est maintenant le bon moment de noter que les listes pour modification vous laissent une grande liberté de mise en page. Par défaut, 100 éléments sont affichés par page. La pagination des listes pour modification, les boîtes de recherche, les filtres, les hiérarchies calendaires et le tri selon l’en-tête de colonne, tout fonctionne ensemble pour une utilisation optimale.

Personnalisation de l’apparence de l’interface d’administration

Clairement, avoir « Django administration » en haut de chaque page d’administration est ridicule. C’est juste du texte de substitution.

Toutefois, c’est facile à modifier en utilisant le système de gabarits de Django. Le site d’administration de Django est fait en Django lui-même, et ses interfaces utilisent le système de gabarits propre à Django.

Personnalisation des gabarits de votre projet

Créez un répertoire s’appelant templates dans le répertoire de votre projet. Les gabarits peuvent se trouver à n’importe quel endroit du système de fichiers, pourvu qu’ils soient accessibles par Django (Django utilise le même utilisateur que celui qui a démarré votre serveur). Cependant, par convention, il est recommandé de conserver les gabarits à l’intérieur du projet.

Ouvrez votre fichier de configuration (mysite/settings.py, souvenez-vous) et ajoutez le réglage TEMPLATE_DIRS :

TEMPLATE_DIRS = (
    '/path/to/mysite/templates', # Change this to your own directory.
)

À présent, copiez le gabarit admin/base_site.html depuis le répertoire par défaut des gabarits de l’interface d’administration de Django dans le code source de Django (django/contrib/admin/templates) vers un sous-répertoire admin se trouvant dans le répertoire que vous avez défini dans TEMPLATE_DIRS. Par exemple, si votre TEMPLATE_DIRS contient '/chemin/vers/mestemplates', copiez django/contrib/admin/templates/admin/base_site.html vers /chemin/vers/mestemplates/admin/base_site.html. N’oubliez pas le sous-répertoire admin.

Où se trouvent les fichiers sources de Django ?

Si vous ne savez pas où les fichiers source de Django se trouvent sur votre système, lancez la commande suivante :

python -c "
import sys
sys.path = sys.path[1:]
import django
print(django.__path__)"

Ensuite, éditez simplement le fichier et remplacez comme bon vous semble le texte générique de Django par le nom de votre propre site.

Ce fichier gabarit contient beaucoup de texte comme {% block branding %} et {{ title }}. Les balises {% et {{ font partie du langage de gabarit de Django. Lorsque Django génère admin/base_site.html, le langage de gabarit est évalué afin de produire la page HTML finale. Ne vous souciez pas de chercher à tout comprendre le contenu du gabarit dans l’immédiat, nous aborderons le langage de gabarit de Django dans le 3ème tutoriel.

Notez que tous les gabarits de l’interface d’administration par défaut de Django peuvent être remplacés. Pour remplacer un gabarit, faites simplement la même chose qu’avec base_site.html, copiez-le depuis le répertoire par défaut dans votre répertoire personnalisé, et faites les modifications nécessaires.

Personnalisation des gabarits de votre application

Les lecteurs avisés demanderont : mais si TEMPLATE_DIRS était vide par défaut, comment Django trouvait-il les gabarits par défaut de l’interface d’administration ? La réponse est que, par défaut, Django regarde automatiquement dans un éventuel sous-répertoire templates/ à l’intérieur de chaque paquet d’application, pour l’utiliser en dernier recours (n’oubliez pas que django.contrib.admin est aussi une application).

Notre application de sondage n’est pas très compliquée et ne nécessite pas de gabarits d’administration personnalisés. Mais si elle devenait plus sophistiquée et qu’il faille modifier les gabarits standards de l’administration de Django pour certaines fonctionnalités, il serait plus logique de modifier les gabarits de l’application, et non pas ceux du projet. De cette façon, vous pourriez inclure l’application « polls » dans tout nouveau projet en étant certain que Django trouve les gabarits personnalisés nécessaires.

Lisez la documentation sur le chargeur de gabarits pour des informations complètes sur la manière dont Django trouve ses gabarits.

Personnalisation de la page d’accueil de l’interface d’administration

De la même manière, il peut être souhaitable de personnaliser l’apparence de la page d’index de l’interface d’administration de Django.

Par défaut, il affiche toutes les applications de INSTALLED_APPS qui ont été inscrites dans l’application admin, par ordre alphabétique. Il est possible de faire des modifications significatives sur la mise en page. Après tout, la page d’index est probablement la page la plus importante du site d’administration, donc autant qu’elle soit facile à utiliser.

Le gabarit à personnaliser est admin/index.html (faites la même chose qu’avec admin/base_site.html dans la précédente section – copiez-le depuis le répertoire par défaut vers votre répertoire de gabarits personnel). Éditez le fichier, et vous verrez qu’il utilise une variable de gabarit appelée app_list. Cette variable contient toutes les applications Django installées et inscrites. À la place, vous pouvez écrire en dur les liens vers les pages d’administration spécifiques aux objets de la manière qui vous convient. Encore une fois, n’essayez pas de tout comprendre le contenu du gabarit, nous aborderons ce sujet plus en détails dans le prochain tutoriel.

Lorsque vous vous serez familiarisé avec le site d’administration, lisez la partie 3 de ce tutoriel pour commencer à travailler avec les vues publiques du sondage.