123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569 |
- <!doctype html>
- <html lang=fr>
- <head>
- <!-- Always define the charset before the title -->
- <meta charset=utf-8>
- <title>Rédaction de votre première appli Django, partie 2 : Exploration de l'interface d'admin auto-générée — Biologeek — David Larlet</title>
- <!-- Define a viewport to mobile devices to use - telling the browser to assume that the page is as wide as the device (width=device-width) and setting the initial page zoom level to be 1 (initial-scale=1.0) -->
- <meta name="viewport" content="width=device-width, initial-scale=1"/>
- <!-- Fake favicon, to avoid extra request to the server -->
- <link rel="icon" href="data:;base64,iVBORw0KGgo=">
- <link type="application/atom+xml" rel="alternate" title="Feed" href="/david/log/" />
- <link rel="manifest" href="/manifest.json">
-
- <link rel="stylesheet" href="/static/david/css/larlet-david-_J6Rv.css" data-instant-track />
-
- <noscript>
- <style type="text/css">
- /* Otherwise fonts are loaded by JS for faster initial rendering. See scripts at the bottom. */
- body {
- font-family: 'EquityTextB', serif;
- }
- h1, h2, h3, h4, h5, h6, time, nav a, nav a:link, nav a:visited {
- font-family: 'EquityCapsB', sans-serif;
- font-variant: normal;
- }
- </style>
- </noscript>
-
- <!-- Canonical URL for SEO purposes -->
- <link rel="canonical" href="https://larlet.fr/david/biologeek/archives/20060617-redaction-de-votre-premiere-appli-django-partie-2-exploration-de-l-interface-d-admin-auto-generee">
-
- </head>
- <body>
- <div>
-
- <header>
- <nav>
- <p>
- <small>
- Je suis <a href="/david/" title="Profil public">David Larlet</a>, <a href="/david/pro/" title="Activité professionnelle">artisan</a> du web qui vous <a href="/david/pro/accompagnement/" title="Activité d’accompagnement">accompagne</a><span class="more-infos"> dans l’acquisition de savoirs pour concevoir des <a href="/david/pro/produits-essentiels/" title="Qu’est-ce qu’un produit essentiel ?">produits essentiels</a></span>. <span class="more-more-infos">Discutons ensemble d’une <a href="/david/pro/devis/" title="En savoir plus">non-demande de devis</a>.</span> Je partage ici mes <a href="/david/blog/" title="Expériences bienveillantes">réflexions</a> et <a href="/david/correspondances/2017/" title="Lettres hebdomadaires">correspondances</a>.
- </small>
- </p>
- </nav>
- </header>
-
-
- <section>
- <h1 property="schema:name">Rédaction de votre première appli Django, partie 2 : Exploration de l'interface d'admin auto-générée</h1>
- <article typeof="schema:BlogPosting">
- <div property="schema:articleBody">
- <img src="/static/david/biologeek/images/logos/django.png" alt="vignette" style="float:left; margin: 0.5em 1em;" property="schema:thumbnailUrl" />
- <p>Ce tutoriel commence là où le <a class="reference" href="https://larlet.fr/david/biologeek/archives/20060617-redaction-de-votre-premiere-appli-django-partie-1-initialisation-creation-des-modeles-et-api-de-la-base-de-donnees/">Tutoriel 1</a> 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.</p>
-
- <div class="section">
- <h1><a id="activer-le-site-d-admin" name="activer-le-site-d-admin">Activer le site d'admin</a></h1>
- <p>Le site d'admin de Django n'est pas activé par défaut -- c'est une
- fonctionnalité optionnelle. Pour activer le site d'admin dans votre
- installation, suivez ces trois points:</p>
- <blockquote>
- <ul class="simple">
-
- <li>Ajoutez <tt class="docutils literal"><span class="pre">"django.contrib.admin"</span></tt> dans votre option <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt>.</li>
- <li>Lancez <tt class="docutils literal"><span class="pre">python</span> <span class="pre">manage.py</span> <span class="pre">syncdb</span></tt>. Puisque vous avez ajouté une nouvelle
- application à <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt>, les tables de la base de données ont
- besoin d'être mises à jour.</li>
-
- <li>Éditez votre fichier <tt class="docutils literal"><span class="pre">monsite/urls.py</span></tt> et décommentez la ligne en
- dessous de « Uncomment this for admin: ». 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 définit la
- racine des URLs de vos applications.</li>
- </ul>
- </blockquote>
- </div>
-
- <div class="section">
- <h1><a id="d-marrer-le-serveur-de-d-veloppement" name="d-marrer-le-serveur-de-d-veloppement">Démarrer le serveur de développement</a></h1>
- <p>Démarrons le serveur de développement et explorons le site d'administration.</p>
- <p>Rappel du Tutoriel 1 : vous démarrez le serveur de développement comme ceci:</p>
- <pre class="literal-block">
- python manage.py runserver
-
- </pre>
- <p>À présent, ouvrez un navigateur Web et allez au « /admin/ » de votre domaine
- local -- par exemple, <a class="reference" href="http://127.0.0.1:8000/admin/">http://127.0.0.1:8000/admin/</a>. Vous devriez voir l'écran de
- connexion à l'interface d'admin:</p>
- <img alt="L'écran de connexion à l'interface d'admin de Django" src="/static/david/biologeek/images/django/admin01.png" />
- </div>
-
- <div class="section">
- <h1><a id="entrez-dans-le-site-d-admin" name="entrez-dans-le-site-d-admin">Entrez dans le site d'admin</a></h1>
- <p>Maintenant, essayez de vous identifier (vous avez créé un compte
- superutilisateur dans la première partie du tutoriel vous vous rappelez ?).
- Vous devriez voir la page d'index de l'interface d'admin de Django:</p>
- <a class="reference image-reference" href="/static/david/biologeek/images/django/admin02.png"><img alt="La page d'index de l'interface d'admin de Django" src="/static/david/biologeek/images/django/admin02t.png" /></a>
- <p>Par défaut, vous deviez voir deux types de contenu éditable : groupes et
- utilisateurs.
- Ce sont des caractéristiques du noyau que Django intègre par défaut.</p>
- </div>
-
- <div class="section">
-
- <h1><a id="rendre-l-appli-de-sondage-modifiable-via-l-interface-d-admin" name="rendre-l-appli-de-sondage-modifiable-via-l-interface-d-admin">Rendre l'appli de sondage modifiable via l'interface d'admin</a></h1>
- <p>Mais où est notre appli de sondage ? Il n'est pas affiché sur la page d'index de
- l'interface d'admin.</p>
- <p>Juste une chose à faire : Nous avons besoin de spécifier dans le modèle <tt class="docutils literal"><span class="pre">Poll</span></tt>
- que les objets <tt class="docutils literal"><span class="pre">Poll</span></tt>
- ont une interface d'admin. Éditez le fichier <tt class="docutils literal"><span class="pre">monsite/polls/models.py</span></tt> et
- faites les modifications suivantes pour ajouter une classe interne <tt class="docutils literal"><span class="pre">Admin</span></tt>:</p>
-
- <pre class="literal-block">
- class Poll(models.Model):
- # ...
- class Admin:
- pass
- </pre>
- <p>La <tt class="docutils literal"><span class="pre">classe</span> <span class="pre">Admin</span></tt> contiendra les paramètres qui contrôle comment ce modèle
- apparaît dans l'interface d'admin de Django. Tous les paramètres sont
- optionnels, cependant, créer ainsi une classe vide signifie « donne une
- interface d'administration à cet objet en utilisant les options par défaut ».</p>
- <p>Maintenant rechargez la page d'admin de Django pour voir les changements. Notez
- que vous n'avez pas à redémarrer le serveur de développement -- le serveur
- auto-recharge votre projet, du coup toute modification dans le code peut être
- visualisé immédiatement dans votre navigateur.</p>
- </div>
-
- <div class="section">
- <h1><a id="explorer-les-fonctionnalit-s-libres-de-l-interface-d-admin" name="explorer-les-fonctionnalit-s-libres-de-l-interface-d-admin">Explorer les fonctionnalités libres de l'interface d'admin</a></h1>
- <p>Maintenant que <tt class="docutils literal"><span class="pre">Poll</span></tt> a sa classe interne <tt class="docutils literal"><span class="pre">Admin</span></tt>, Django sait qu'il devrait
- être affiché sur la page d'index du site d'admin:</p>
-
- <a class="reference image-reference" href="/static/david/biologeek/images/django/admin03.png"><img alt="La page d'index du site d'admin de Django, maintenant avec les sondages d'affichés" src="/static/david/biologeek/images/django/admin03t.png" /></a>
- <p>Cliquez sur « Polls ». À présent, vous êtes sur la page « de listage pour
- modification » des sondages. Cette page affiche tous les sondages de la base de
- données et vous permet d'en choisir un pour l'éditer.
- Il y a le sondage « Quoi de neuf ? » que nous avons créé dans le premier
- tutoriel:</p>
- <a class="reference image-reference" href="/static/david/biologeek/images/django/admin04.png"><img alt="La page de listage pour modification" src="/static/david/biologeek/images/django/admin04t.png" /></a>
- <p>Cliquez sur le sondage « Quoi de neuf ? » pour l'éditer :</p>
- <a class="reference image-reference" href="/static/david/biologeek/images/django/admin05.png"><img alt="Formulaire d'édition pour un objet sondage poll" src="/static/david/biologeek/images/django/admin05t.png" /></a>
- <p>Choses à noter ici:</p>
- <ul class="simple">
- <li>Le formulaire est généré automatiquement depuis le modèle Poll.</li>
- <li>Les différents types de champs du modèle (<tt class="docutils literal"><span class="pre">models.DateTimeField</span></tt>,
- <tt class="docutils literal"><span class="pre">models.CharField</span></tt>) correspondent au widget d'entrée HTML approprié. Chaque
- type de champ sait comment s'afficher dans l'interface d'admin de Django.</li>
-
- <li>Chaque <tt class="docutils literal"><span class="pre">DateTimeField</span></tt> reçoit des raccourcis Javascript libre. 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.</li>
- </ul>
- <p>La partie inférieur de la page vous propose une série d'opérations:</p>
- <ul class="simple">
- <li>Sauver -- Sauvegarde les modifications et retourne à la page de listage pour
- modification pour ce type d'objet.</li>
- <li>Sauver et continuer les modifications -- Sauvegarde les modifications et
- recharge la page d'administration de cet objet.</li>
- <li>Sauver et ajouter un nouveau -- Sauvegarde les modifications et charge un
- nouveau formulaire vierge pour ce type d'objet.</li>
- <li>Supprimer -- Affiche la page de confirmation de la suppression.</li>
-
- </ul>
- <p>Changez la « Date de publication » en cliquant sur les raccourcis
- « Aujourd'hui » et « Maintenant ». Puis cliquez sur « Sauver 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:</p>
- <a class="reference image-reference" href="/static/david/biologeek/images/django/admin06.png"><img alt="La page d'historique pour l'objet de sondage poll" src="/static/david/biologeek/images/django/admin06t.png" /></a>
- </div>
-
- <div class="section">
- <h1><a id="personnaliser-le-formulaire-d-administration" name="personnaliser-le-formulaire-d-administration">Personnaliser le formulaire d'administration</a></h1>
- <p>Prenez quelques minutes pour vous émerveiller devant le code que vous n'avez
- pas dû écrire.</p>
- <p>Personnalisons un peu tout ça. Nous pouvons réordonner les champs en ajoutant
- explicitement un paramètre <tt class="docutils literal"><span class="pre">fields</span></tt> à <tt class="docutils literal"><span class="pre">Admin</span></tt>:</p>
-
- <pre class="literal-block">
- class Admin:
- fields = (
- (None, {'fields': ('pub_date', 'question')}),
- )
- </pre>
- <p>Cela fait que la « Date de publication » apparaît en premier au lieu d'être en
- second:</p>
- <img alt="Les champs ont été réordonnés" src="/static/david/biologeek/images/django/admin07.png" />
- <p>Ce n'est pas spécialement impressionnant avec seulement deux champs, mais pour
- un formulaire d'administration avec des douzaines de champs, choisir un ordre
- intuitif est un détail d'utilisation important.</p>
- <p>Et en parlant de formulaires avec des douzaines de champs, vous voudriez
- sûrement séparer le formulaire en plusieurs sous-ensembles:</p>
- <pre class="literal-block">
- class Admin:
- fields = (
- (None, {'fields': ('question',)}),
- ('Informations calendaires', {'fields': ('pub_date',)}),
- )
- </pre>
- <p>Le premier élément de chaque tuple dans <tt class="docutils literal"><span class="pre">fields</span></tt> est le titre de la
- sous-partie. Voici ce à quoi notre formulaire ressemble à présent:</p>
-
- <a class="reference image-reference" href="/static/david/biologeek/images/django/admin08.png"><img alt="Le formulaire a des sous-sensembles de champs à présent" src="/static/david/biologeek/images/django/admin08t.png" /></a>
- <p>Vous pouvez assigner des classes HTML arbitraires à chaque sous-ensemble. Django
- fournit une classe <tt class="docutils literal"><span class="pre">"collapse"</span></tt> 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:</p>
- <pre class="literal-block">
- class Admin:
- fields = (
- (None, {'fields': ('question',)}),
- ('Informations calendaires', {'fields': ('pub_date',), 'classes': 'collapse'}),
- )
- </pre>
- <img alt="Le sous-ensemble est initialement replié" src="/static/david/biologeek/images/django/admin09.png" />
- </div>
-
- <div class="section">
- <h1><a id="ajout-d-objets-li-s" name="ajout-d-objets-li-s">Ajout d'objets liés</a></h1>
- <p>OK, nous avons notre page d'administration de sondages Poll. Mais un sondage
- <tt class="docutils literal"><span class="pre">Poll</span></tt> possède plusieurs choix <tt class="docutils literal"><span class="pre">Choices</span></tt>, et la page d'admin n'affiche aucun
- choix.</p>
-
- <p>Pour le moment.</p>
- <p>Il y a deux façon de résoudre ce problème. Le premier et de donner au modèle
- <tt class="docutils literal"><span class="pre">Choice</span></tt> sa propre classe interne <tt class="docutils literal"><span class="pre">Admin</span></tt>, tout comme nous l'avons fait pour
- <tt class="docutils literal"><span class="pre">Poll</span></tt>. Voici ce que ça donnerait:</p>
- <pre class="literal-block">
- class Choice(models.Model):
- # ...
- class Admin:
- pass
- </pre>
- <p>Maintenant les choix sont une option disponible dans l'interface d'admin de
- Django. Le formulaire « Add choice » ressemble à ceci:</p>
- <img alt="Page d'administration de Choice" src="/static/david/biologeek/images/django/admin10.png" />
-
- <p>Dans ce formulaire, le champ « Poll » est une boîte de sélection contenant tous
- les sondages de la base de données. Django sait qu'une instance de
- <tt class="docutils literal"><span class="pre">ForeignKey</span></tt> devrait être représentée dans l'interface d'admin par une boîte
- <tt class="docutils literal"><span class="pre"><select></span></tt>. Dans notre cas, seul un sondage existe à ce point.</p>
- <p>Notez également le lien « Add another » à côté de « Poll ». Chaque objet avec
- une relation ForeignKey vers un autre reçoit ce lien gratuitement. Quand vous
- cliquez sur « Add another », vous obtiendrez une fenêtre en popup quand le
- formulaire « Add poll ». Si vous ajoutez un sondage dans cette fenêtre et que
- vous cliquez sur « Sauver », Django sauvegardera le sondage dans la base de
- données et l'ajoutera dynamiquement comme choix sélectionné dans le formulaire
- « Add choice » que vous étiez en train de remplir.</p>
- <p>Mais, franchement, c'est une manière inefficace d'ajouter des objets « Choice »
- dans le système. Ça serait mieux si vous pouviez ajouter un groupe de choix
- « Choices » directement lorsque vous créez l'objet « Poll ». Faisons de cette
- façon.</p>
- <p>Retirez la classe <tt class="docutils literal"><span class="pre">Admin</span></tt> du modèle Choice. Puis, éditez le champ
- <tt class="docutils literal"><span class="pre">ForeignKey(Poll)</span></tt> comme ceci:</p>
-
- <pre class="literal-block">
- poll = models.ForeignKey(Poll, edit_inline=models.STACKED, num_in_admin=3)
- </pre>
- <p>Ça dit à Django: « Les objets Choice sont édités dans la page d'administration
- de Poll. Par défaut, fournir assez de champs pour 3 choix ».</p>
- <p>Ensuite, modifiez les autres champs dans <tt class="docutils literal"><span class="pre">Choice</span></tt> pour les mettre à
- <tt class="docutils literal"><span class="pre">core=True</span></tt>:</p>
- <pre class="literal-block">
- choice = models.CharField(maxlength=200, core=True)
- votes = models.IntegerField(core=True)
- </pre>
- <p>Ça dit à Django: « Quand tu édites un Choice dans la page d'admin de Poll, les
- champs 'choice' et 'votes' sont requis. La présence d'au moins un d'eux signifie
- que l'ajout d'un nouvel objet Choice, et que la mise à blanc de tous ces champs
- signifie la suppression de cet objet Choice existant ».</p>
-
- <p>Charger la page « Add poll » pour voir à quoi ça ressemble:</p>
- <a class="reference image-reference" href="/static/david/biologeek/images/django/admin11.png"><img alt="La page d'ajout de sondage contient maintenant des choix" src="/static/david/biologeek/images/django/admin11t.png" /></a>
- <p>Ça marche comme ceci : Il y a trois compartiments pour les choix « Choices »
- liés -- comme spécifié par <tt class="docutils literal"><span class="pre">num_in_admin</span></tt> -- mais chaque fois que vous revenez
- sur la page « Changement » d'un objet déjà créé, vous obtenez un compartiment
- supplémentaire (cela signifie que vous n'avez pas mis en dur de limite sur le
- nomble d'objets liés qui peuvent être ajoutés). Si vous aviez voulu de la place
- pour trois choix « Choices » supplémentaire à chaque fois que vous modifiez le
- sondage, vous auriez utilisé <tt class="docutils literal"><span class="pre">num_extra_on_change=3</span></tt>.</p>
- <p>Un petit problème cependant. Ça prend beaucoup de place d'afficher tous les
- champs pour saisir les objets « Choice » liés. C'est pour cette raison que
- Django offre une alternative d'affichage en ligne des objets liés:</p>
- <pre class="literal-block">
- poll = models.ForeignKey(Poll, edit_inline=models.TABULAR, num_in_admin=3)
- </pre>
- <p>Avec ce <tt class="docutils literal"><span class="pre">edit_inline=models.TABULAR</span></tt> (au lieu de <tt class="docutils literal"><span class="pre">models.STACKED</span></tt>), les
- objets liés sont affichés dans un format plus compact, comme un tableau:</p>
-
- <img alt="La page d'ajout de sondage a maintenant des choix plus compacts" src="/static/david/biologeek/images/django/admin12.png" />
- </div>
-
- <div class="section">
- <h1><a id="personnaliser-la-liste-pour-modification-de-l-interface-d-admin" name="personnaliser-la-liste-pour-modification-de-l-interface-d-admin">Personnaliser la liste pour modification de l'interface d'admin</a></h1>
- <p>Maintenant que la page d'admin des sondage « Poll » a un bon look, arrangeons un
- peu la page de « listage pour modification » -- celle qui affiche tous les
- sondages du système.</p>
- <p>Voici à quoi ça ressemble à ce point:</p>
- <a class="reference image-reference" href="/static/david/biologeek/images/django/admin04.png"><img alt="La page de listage pour modification des sondages Poll" src="/static/david/biologeek/images/django/admin04t.png" /></a>
- <p>Par défaut, Django affiche le <tt class="docutils literal"><span class="pre">str()</span></tt> de chaque objet. Mais parfois, ça serait
- plus utile si nous pouvions afficher des champs individuels. Dans ce but,
- utilisez l'option <tt class="docutils literal"><span class="pre">list_display</span></tt>, qui est un tuple de nom de champs à
- afficher, en colonnes, sur la page de listage pour modification de l'objet:</p>
-
- <pre class="literal-block">
- class Poll(models.Model):
- # ...
- class Admin:
- # ...
- list_display = ('question', 'pub_date')
- </pre>
- <p>Juste pour la démonstration, incluons également la méthode perso
- <tt class="docutils literal"><span class="pre">was_published_today</span></tt> du Tutoriel 1:</p>
- <pre class="literal-block">
- list_display = ('question', 'pub_date', 'was_published_today')
- </pre>
- <p>À présent la page de listage pour modification des sondage ressemble à ceci:</p>
- <a class="reference image-reference" href="/static/david/biologeek/images/django/admin13.png"><img alt="La page de listage pour modification, mise à jour" src="/static/david/biologeek/images/django/admin13t.png" /></a>
- <p>Vous pouvez cliquer sur les en-têtes de colonne pour trier selon ces valeurs --
- sauf dans le cas de l'en-tête <tt class="docutils literal"><span class="pre">was_published_today</span></tt>, parce que le tri selon le
- résultat d'une méthode arbitraire n'est pas supporté. Notez aussi que l'en-tête
- de la colonne pour <tt class="docutils literal"><span class="pre">was_published_today</span></tt> est, par défaut, le nom de la méthode
- (avec les underscores remplacés par des espaces. Mais vous pouvez changer cela
- en donnant à cette méthode un attribut <tt class="docutils literal"><span class="pre">short_description</span></tt>:</p>
-
- <pre class="literal-block">
- def was_published_today(self):
- return self.pub_date.date() == datetime.date.today()
- was_published_today.short_description = u'Publié aujourd\'hui ?'
- </pre>
- <p>Ajoutons une nouvelle amélioration à la page de listage pour modification de
- sondages : des filtres. Ajoutez la ligne suivante à <tt class="docutils literal"><span class="pre">Poll.Admin</span></tt>:</p>
- <pre class="literal-block">
- list_filter = ['pub_date']
- </pre>
- <p>Cela ajoute une sidebar « Filter » qui permet aux gens de filtrer la liste pour
- modification selon le champ <tt class="docutils literal"><span class="pre">pub_date</span></tt>:</p>
- <a class="reference image-reference" href="/static/david/biologeek/images/django/admin14.png"><img alt="La page de listage pour modification de sondages, mise à jour" src="/static/david/biologeek/images/django/admin14t.png" /></a>
- <p>Le type de filtre affiché dépend du type de champs que vous êtes en train de
- filtrer. Parce que <tt class="docutils literal"><span class="pre">pub_date</span></tt> est un DateTimeField, Django sait donner les
- options de filtrage par défaut pour les DateTimeFields: « Toutes les dates »,
- « Aujourd'hui », « Les 7 derniers jours », « Ce mois-ci », « Cette année ».</p>
-
- <p>Ça a meilleure forme. Ajoutons une fonctionnalité de recherche:</p>
- <pre class="literal-block">
- search_fields = ['question']
- </pre>
- <p>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
- <tt class="docutils literal"><span class="pre">question</span></tt>. Vous pouvez indiquer autant de champs que vous le désirez -- bien
- qu'il utilise un requête <tt class="docutils literal"><span class="pre">LIKE</span></tt> derrière, restez raisonnable pour garder votre
- base de données performante.</p>
- <p>Enfin, parce que les objets « Poll » ont des dates, il serait pratique
- d'effectuer un classement par date. Ajoutez cette ligne:</p>
- <pre class="literal-block">
- date_hierarchy = 'pub_date'
- </pre>
-
- <p>Cela ajoute une navigation hiérarchique, par date, en haut de la page de listage
- pour modification. Au premier niveau, il affiche toutes les années disponibles.
- Puis il affine le classement en mois et, finalement, en jours.</p>
- <p>C'est maintenant le bon moment de notez que les listes pour modification vous
- laissent une grande liberté de pagination. Par défaut, 50 items sont affichés
- par page. La pagination de 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 comme vous pensez qu'ils le devraient.</p>
- </div>
-
- <div class="section">
- <h1><a id="personnaliser-l-apparence-de-l-interface-d-administration" name="personnaliser-l-apparence-de-l-interface-d-administration">Personnaliser l'apparence de l'interface d'administration</a></h1>
- <p>C'est clair, avoir « Django administration » et « example.com » en haut de
- chaque page d'administration est ridicule. C'est juste du texte de substitution.</p>
- <p>C'est facile à modifier en utilisant le système de template de Django. Le site
- d'administration de Django est fait en Django lui-même, et ses interfaces
- utilisent le système de template propre à Django. (Ça devient métaphysique !)</p>
- <p>Ouvrez votre fichier de configuration (<tt class="docutils literal"><span class="pre">monsite/settings.py</span></tt>, souvenez-vous)
- et examinez l'option <tt class="docutils literal"><span class="pre">TEMPLATE_DIRS</span></tt>. <tt class="docutils literal"><span class="pre">TEMPLATE_DIRS</span></tt> est un tuple de
- répertoires du système de fichiers pour vérifier d'où les templates Django sont
- chargées. C'est un chemin de recherche.</p>
-
- <p>Par défaut, <tt class="docutils literal"><span class="pre">TEMPLATE_DIRS</span></tt> est vide. Donc, ajoutons-lui une ligne pour dire à
- Django où nos templates sont situées:</p>
- <pre class="literal-block">
- TEMPLATE_DIRS = (
- "/home/mestemplates", # Remplacez par votre propre répertoire.
- )
- </pre>
- <p>À présent, copiez la template <tt class="docutils literal"><span class="pre">admin/base_site.html</span></tt> depuis le répertoire par
- défaut des templates de l'interface d'admin de Django
- (<tt class="docutils literal"><span class="pre">django/contrib/admin/templates</span></tt>) vers un sous-répertoire <tt class="docutils literal"><span class="pre">admin</span></tt> se
- trouvant dans le répertoire que vous avez défini dans <tt class="docutils literal"><span class="pre">TEMPLATE_DIRS</span></tt>. Par
- exemple, si votre <tt class="docutils literal"><span class="pre">TEMPLATE_DIRS</span></tt> contient <tt class="docutils literal"><span class="pre">"/home/mestemplates"</span></tt>, comme
- ci-dessus, copiez <tt class="docutils literal"><span class="pre">django/contrib/admin/templates/admin/base_site.html</span></tt> vers
-
- <tt class="docutils literal"><span class="pre">/home/mytemplates/admin/base_site.html</span></tt>. N'oubliez pas de créer au préalable
- ce sous-répertoire <tt class="docutils literal"><span class="pre">admin</span></tt>.</p>
- <p>Ensuite, éditez simplement le fichier et remplacez le texte générique de Django
- par le nom et l'URL de votre propre site.</p>
- <p>Notez que tous les templates de l'interface d'admin par défaut de Django
- peuvent être remplacés. Pour remplacer un template, faites simplement la même
- chose qu'avec <tt class="docutils literal"><span class="pre">base_site.html</span></tt> -- copiez le depuis le répertoire par défaut
- dans votre répertoire personnel, et faites les modifications.</p>
- <p>Les lecteurs avisés pourront demander : Mais si <tt class="docutils literal"><span class="pre">TEMPLATE_DIRS</span></tt> était vide par
- défaut, comment Django trouvait-il les templates par défaut de l'interface
- d'admin ? La réponse est que, par défaut, Django regarde automatiquement dans un
- éventuel sous-répertoire <tt class="docutils literal"><span class="pre">templates/</span></tt> à l'intérieur de chaque paquetage
- d'appli, pour l'utiliser en dernier recours. Lisez la <a class="reference" href="http://www.djangoproject.com/documentation/templates_python/#loader-types">documentation sur les
- types de chargeur</a> pour des informations complètes.</p>
-
- </div>
-
- <div class="section">
- <h1><a id="personnaliser-la-page-d-index-de-l-interface-d-admin" name="personnaliser-la-page-d-index-de-l-interface-d-admin">Personnaliser la page d'index de l'interface d'admin</a></h1>
- <p>De la même manière, vous voudriez sûrement personnaliser l'apparence de la page
- d'index de l'interface d'admin de Django.</p>
- <p>Par défaut, il affiche toutes les applis disponibles, selon la configuration de
- votre <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt>. Mais l'ordre dans lequel il affiche les éléments est
- aléatoire, et vous voudriez peut-être 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.</p>
- <p>Le template à personnaliser est <tt class="docutils literal"><span class="pre">admin/index.html</span></tt>. (Faites la même chose
- qu'avec <tt class="docutils literal"><span class="pre">admin/base_site.html</span></tt> dans la précédente section -- copiez le depuis
- le répertoire par défaut vers votre répertoire de templates personnels.)
- Éditez le fichier, et vous verrez qu'il est utilisé une balise de template
- appelé <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">get_admin_app_list</span> <span class="pre">as</span> <span class="pre">app_list</span> <span class="pre">%}</span></tt>. C'est l'instruction magique qui
- retrouve chaque appli Django installée. Au lieu d'utiliser ça, vous pouvez
- écrire en dur les liens vers les pages d'administration spécifiques aux objets
- de la meilleure manière que vous pensez.</p>
-
- <p>Django offre un autre raccourci dans cette procédure. Lancez la commande
- <tt class="docutils literal"><span class="pre">python</span> <span class="pre">manage.py</span> <span class="pre">adminindex</span> <span class="pre">polls</span></tt> pour obtenir un extrait de code de
- template à inclure dans la template de la page d'index de l'interface d'admin.
- C'est un point de départ plutôt utile.</p>
- <p>Pour des détails complets au sujet de la personnalisation de l'apparence du site
- d'administration de Django de manière générale, lisez le <a class="reference" href="http://www.djangoproject.com/documentation/admin_css/">guide CSS de
- l'interface d'admin de Django</a>.</p>
- <p>Lorsque vous vous serez familiarisé avec le site d'administration, lisez la
- <a class="reference" href="https://larlet.fr/david/biologeek/archives/20060617-redaction-de-votre-premiere-appli-django-partie-3-creation-des-vues-de-l-interface-publique/">partie 3 de ce tutoriel</a> pour commencer à travailler avec les vues publiques
- du sondage.</p>
-
- <p>Vous pouvez maintenant retourner à la <a class="reference" href="https://larlet.fr/david/biologeek/archives/20060617-traduction-francaise-de-la-documentation-de-django-le-framework-web-python/">page d'accueil des traductions de la
- documentation de Django</a>.</p>
- <p>Cette traduction correspond à la révision 3589 (post 0.95).</p>
- </div>
- </div>
- </article>
- <footer>
- <h6 property="schema:datePublished">— 17/06/2006</h6>
- </footer>
- </section>
- <section>
- <div>
- <h3>Articles peut-être en rapport</h3>
- <ul>
- <li><a href="/david/biologeek/archives/20060815-le-langage-de-template-django-pour-les-auteurs-de-templates/" title="Accès à Le langage de template Django : Pour les auteurs de templates">Le langage de template Django : Pour les auteurs de templates</a></li>
- <li><a href="/david/biologeek/archives/20060715-comparaison-de-turbogears-et-django-deux-frameworks-web-python/" title="Accès à Comparaison de TurboGears et Django, deux frameworks web Python">Comparaison de TurboGears et Django, deux frameworks web Python</a></li>
- <li><a href="/david/biologeek/archives/20060617-redaction-de-votre-premiere-appli-django-partie-4-conception-d-un-formulaire-et-vues-generiques/" title="Accès à Rédaction de votre première appli Django, partie 4 : Conception d'un formulaire et vues génériques">Rédaction de votre première appli Django, partie 4 : Conception d'un formulaire et vues génériques</a></li>
- </ul>
- </div>
- </section>
- <section>
- <div id="comments">
- <h3>Commentaires</h3>
-
- <div class="comment" typeof="schema:UserComments">
- <p class="comment-meta">
- <span class="comment-author" property="schema:creator">Flipper</span> le <span class="comment-date" property="schema:commentTime">05/08/2006</span> :
- </p>
- <div class="comment-content" property="schema:commentText">
- <p>Très bonne traduction, merci!<br />
- Il y a un "u" qui traine dans l'attribut short_description...</p>
- </div>
- </div>
- <div class="comment" typeof="schema:UserComments">
- <p class="comment-meta">
- <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">05/08/2006</span> :
- </p>
- <div class="comment-content" property="schema:commentText">
- <p>Le « u » est pour le passage en unicode histoire de gérer les accents français.</p>
- </div>
- </div>
- <div class="comment" typeof="schema:UserComments">
- <p class="comment-meta">
- <span class="comment-author" property="schema:creator">Eric</span> le <span class="comment-date" property="schema:commentTime">11/09/2006</span> :
- </p>
- <div class="comment-content" property="schema:commentText">
- <p>Bonjour,<br />
- <br />
- was_published_today.short_description = u'Publié aujourd\'hui ?'<br />
- <br />
- Créé une erreur d'Unicode :<br />
- UnicodeEncodeError at /admin/polls/poll/<br />
- 'ascii' codec can't encode character u'\xe9' in position 5: ordinal not in range(128)<br />
- <br />
- novice en Python, le seul moyen que j'ai trouvé pour contourner ce probléme c'est d'utiliser la synthaxe suivante :<br />
- <br />
- was_published_today.short_description = 'Publi&eacute; aujourd\'hui ?'<br />
- <br />
- Ca fonctionne ... mais il y a certainement mieux à faire ... :) <br />
- Eric</p>
- </div>
- </div>
- <div class="comment" typeof="schema:UserComments">
- <p class="comment-meta">
- <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">11/09/2006</span> :
- </p>
- <div class="comment-content" property="schema:commentText">
- <p>Vérifie l'encodage de caractère (ou charset) de ton fichier source. S'il est en utf-8 ça devrait passer (auquel cas, il faudra déclarer la page de template en utf-8 aussi).</p>
- </div>
- </div>
- <div class="comment" typeof="schema:UserComments">
- <p class="comment-meta">
- <span class="comment-author" property="schema:creator">Eric</span> le <span class="comment-date" property="schema:commentTime">12/09/2006</span> :
- </p>
- <div class="comment-content" property="schema:commentText">
- <p>Entre temps je me suis documenté, j'utilise donc Django avec Ptyhon 2.4, sur windows Xp et ...<br />
- A partir de la version 2.3 de Python il est fortement conseillé aux francophones d'inclure un pseudo-commentaire au début de tous leurs scripts Python (obligatoirement à la 1ere ou à la 2ème ligne)<br />
- <br />
- # -*- coding : Latin-1 -*-<br />
- <br />
- Ou bien<br />
- <br />
- # -*- coding : Utf-8 -*-<br />
- <br />
- ce qui est tout de même une meilleure solution que la précédente ;)<br />
- Eric</p>
- </div>
- </div>
- <div class="comment" typeof="schema:UserComments">
- <p class="comment-meta">
- <span class="comment-author" property="schema:creator">Hafid</span> le <span class="comment-date" property="schema:commentTime">24/08/2010</span> :
- </p>
- <div class="comment-content" property="schema:commentText">
- <p>Bonjour,</p>
-
- <p>Tout d'abord je vous remercie pour ce site et pour tout ce travail fourni</p>
-
- <p>Je suis en train d'apprendre à travailler avec django en suivant ce tutorial Mais je rencontre un bug au niveau:<br />"Rendre l'appli de sondage modifiable via l'interface d'admin". J'ajoute la classe interne Admin dans le fichiers polls/models.py mais rien ne change dans mon admin. Pensez-vous que j'ai oublié un détail de configuration?<br />NB: je suis sous windows, j'utilise la dernière version de django et python 2.6</p>
-
- <p>Merci d'avance pour votre réponse</p>
- </div>
- </div>
-
- </div>
- </section>
-
-
- <footer>
- <nav>
- <p>
- <small>
- Je réponds quasiment toujours aux <a href="mailto:david%40larlet.fr" title="Envoyer un email">emails</a> (<a href="/david/signature/" title="Ma signature actuelle avec possibilité de chiffrement">signés</a>) et vous pouvez me rencontrer à Montréal. <span class="more-infos">N’hésitez pas à <a href="/david/log/" title="Être tenu informé des mises à jour">vous abonner</a> pour être tenu informé des publications récentes.</span>
- </small>
- </p>
- </nav>
- </footer>
-
- </div>
-
- <script src="/static/david/js/larlet-david-3ee43f.js" data-no-instant></script>
-
- <script data-no-instant>InstantClick.init()</script>
-
- </body>
- </html>
|