Repository with sources and generator of https://larlet.fr/david/ https://larlet.fr/david/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.html 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. <!doctype html>
  2. <html lang=fr>
  3. <head>
  4. <!-- Always define the charset before the title -->
  5. <meta charset=utf-8>
  6. <title>Vues génériques, héritage et templatetags : développez rapidement avec Django — Biologeek — David Larlet</title>
  7. <!-- 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) -->
  8. <meta name="viewport" content="width=device-width, initial-scale=1"/>
  9. <!-- Fake favicon, to avoid extra request to the server -->
  10. <link rel="icon" href="data:;base64,iVBORw0KGgo=">
  11. <link type="application/atom+xml" rel="alternate" title="Feed" href="/david/log/" />
  12. <link rel="manifest" href="/manifest.json">
  13. <link rel="stylesheet" href="/static/david/css/larlet-david-_J6Rv.css" data-instant-track />
  14. <noscript>
  15. <style type="text/css">
  16. /* Otherwise fonts are loaded by JS for faster initial rendering. See scripts at the bottom. */
  17. body {
  18. font-family: 'EquityTextB', serif;
  19. }
  20. h1, h2, h3, h4, h5, h6, time, nav a, nav a:link, nav a:visited {
  21. font-family: 'EquityCapsB', sans-serif;
  22. font-variant: normal;
  23. }
  24. </style>
  25. </noscript>
  26. <!-- Canonical URL for SEO purposes -->
  27. <link rel="canonical" href="https://larlet.fr/david/biologeek/archives/20070424-vues-generiques-heritage-et-templatetags-developpez-rapidement-avec-django">
  28. </head>
  29. <body>
  30. <div>
  31. <header>
  32. <nav>
  33. <p>
  34. <small>
  35. 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>.
  36. </small>
  37. </p>
  38. </nav>
  39. </header>
  40. <section>
  41. <h1 property="schema:name">Vues génériques, héritage et templatetags : développez rapidement avec Django</h1>
  42. <article typeof="schema:BlogPosting">
  43. <div property="schema:articleBody">
  44. <img src="/static/david/biologeek/images/logos/biologeek.png" alt="vignette" style="float:left; margin: 0.5em 1em;" property="schema:thumbnailUrl" />
  45. <p>Suite de la <a href="https://larlet.fr/david/biologeek/archives/20070224-objectifs-et-motivations-de-la-refonte-de-ce-blog/">saga consacrée à la refonte de ce site</a>. Aujourd'hui, on s'attaque à la partie visible de l'iceberg avec des petits raccourcis de Django qui changent la vie™.</p>
  46. <h2>URL et vues génériques</h2>
  47. <p>Les vues génériques sont issues d'un constat simple&nbsp;: <strong>beaucoup de sites sont destinés à afficher des informations au sujet d'une ressource ou à afficher une liste de ressources</strong>. C'est justement le cas des billets d'un blog donc on ne va pas s'en priver&nbsp;! Par exemple si je considère ma <strong>ressource Post</strong>, je peux définir ma vue ainsi&nbsp;:</p>
  48. <pre>urlpatterns = patterns('django.views.generic.list_detail',
  49. (r'^([-\w]+,)*[-\w]+/(?P&lt;slug&gt;[-\w]+)/$',
  50. 'object_detail',
  51. dict(
  52. queryset = Post.published.all(),
  53. template_object_name = 'post',
  54. slug_field='slug'
  55. )
  56. ),
  57. )</pre>
  58. <p>L'expression régulière récupère ce qui est en <strong>/tag1,tag2/titre-du-billet/</strong> et appelle la vue générique <strong>object_detail</strong> pour afficher le <strong>Post</strong> qui va matcher avec le slug (qui est le titre du billet sous forme d'<abbr title="Uniform Resource Locator">URL</abbr>). C'est tout simple et je n'ai plus qu'à me soucier du template associé pour afficher les informations souhaitées.</p>
  59. <p>Dans le cas d'une <strong>agrégation de ressources</strong> (comme pour le journal par exemple), la définition ressemble à&nbsp;:</p>
  60. <pre>urlpatterns = patterns('django.views.generic.list_detail',
  61. (r'^journal/$',
  62. 'object_list',
  63. dict(
  64. queryset = Post.published.all()[:10],
  65. template_object_name = 'post'
  66. )
  67. ),
  68. )</pre>
  69. <p>Ici on appelle <strong>object_list</strong> pour afficher à l'URL <strong>/journal/</strong> la liste des derniers billets publiés. Je préfère spécifier à chaque fois le <em>template_object_name</em> car j'aime bien savoir ce que je manipule dans les templates (par défaut le nom de la variable est <em>object</em>).</p>
  70. <p>Comme vous pouvez le voir <a href="http://biologeek.googlecode.com/svn/trunk/urls.py">dans le fichier complet</a>, <strong>un blog est défini en quelques lignes de code seulement</strong>... c'est toute la puissance de Django.</p>
  71. <h2>Héritage des templates</h2>
  72. <p>Une autre fonctionnalité qui permet de gagner énormément de temps. <strong>L'héritage des templates de Django est assez pythonique si l'on se représente les fichiers comme des classes et les blocs comme des fonctions</strong>. Chaque template peut hériter d'un template parent et peut surclasser les blocs existants dans ce template en définissant des blocs du même nom (il est aussi possible d'utiliser le contenu des blocs parents en plus du contenu propre au bloc du template courant avec <strong><q> block.super </q></strong>). J'ai du mal à expliquer clairement ce fonctionnement donc le mieux c'est peut-être d'aller lire <a href="http://www2.jeffcroft.com/blog/2006/feb/25/django-templates-the-power-of-inheritance/">le billet de Jeff Croft</a> à ce sujet qui contient des exemples.</p>
  73. <p>Au début on ne se rend pas vraiment compte de la puissance d'un tel système mais à l'utilisation c'est vraiment du <abbr title="Don&#039;t Repeat Yourself">DRY</abbr> à l'état pur.</p>
  74. <h2>Ces petits bouts de code...</h2>
  75. <p>... qui permettent de gagner du temps. Ils ont appelé ça <strong>templatetags</strong> dans django. Les fonctions définies de la sorte peuvent être facilement appelées dans un template pour afficher des informations particulières, c'est généralement utilisé lorsque vous devez avoir accès à des informations similaires à plusieurs endroits du site et que vous ne voulez pas avoir à récupérer cette information dans chaque vue. Un bon exemple vaut mieux qu'un long discours, je veux par exemple afficher les 5 derniers billets publiés dans le pied de page du site. Seules deux lignes sont nécessaires au niveau de mon template&nbsp;:</p>
  76. <pre>{% get_latest_objects journal.Post 5 as latest_posts %}
  77. {% display_footer_posts %}</pre>
  78. <p>Le premier appel récupère les 5 objets de type Post et les place dans la variable <em>latest_post</em>. Le second est un <em>inclusion tag</em> qui à partir de cette variable et d'un bout de template va générer la liste attendue (en html). Certains des templates sont génériques et <a href="http://code.google.com/p/django-template-utils/">partagés</a> donc c'est autant de code à produire en moins. À ce sujet, <a href="http://www.djangosnippets.org/">DjangoSnippets</a> est une excellente ressource aussi.</p>
  79. <p><strong>J'espère que ces quelques exemples vous auront convaincu de la rapidité de développement avec Django</strong> (même si je sais bien que la refonte traîne un peu... ce qui n'est pas vraiment la meilleure publicité que l'on puisse faire ;-)).</p>
  80. <p>Prochaine étape&nbsp;: ma bête noire, <a href="https://larlet.fr/david/biologeek/archives/20070523-de-dotclear-a-django-migration-des-donnees-et-redirections/">la migration des données</a>. C'est dommage car <a href="http://www.aswmc.com/dbmigration/">des solutions sont en train d'être mises en place</a> afin de faciliter ce genre d'opérations mais bon j'ai déjà assez attendu comme ça, je pense que je vais le faire à la main (d'ailleurs si vous avez des conseils/outils). À signaler également la sortie de <a href="http://code.google.com/p/django-openid/">Django OpenID</a> développé par <a href="http://simonwillison.net/2007/Apr/24/openidconsumer/">Simon Willison</a> (M. OpenID mais aussi à l'origine de Django), je suivais l'évolution du projet et je comptais justement lui demander s'il avait une date de prévue pour la sortie, c'est maintenant chose faite, ça va pas mal me simplifier la tâche.</p>
  81. </div>
  82. </article>
  83. <footer>
  84. <h6 property="schema:datePublished">— 24/04/2007</h6>
  85. </footer>
  86. </section>
  87. <section>
  88. <div>
  89. <h3>Articles peut-être en rapport</h3>
  90. <ul>
  91. <li><a href="/david/biologeek/archives/20080423-biologeek-enfin-propulse-par-django/" title="Accès à Biologeek (enfin) propulsé par Django">Biologeek (enfin) propulsé par Django</a></li>
  92. <li><a href="/david/biologeek/archives/20070623-ajout-des-flux-rss-du-sitemap-et-des-commentaires-avec-django/" title="Accès à Ajout des flux RSS, du sitemap et des commentaires avec Django">Ajout des flux RSS, du sitemap et des commentaires avec Django</a></li>
  93. <li><a href="/david/biologeek/archives/20070523-de-dotclear-a-django-migration-des-donnees-et-redirections/" title="Accès à De Dotclear à Django : migration des données et redirections">De Dotclear à Django : migration des données et redirections</a></li>
  94. </ul>
  95. </div>
  96. </section>
  97. <section>
  98. <div id="comments">
  99. <h3>Commentaires</h3>
  100. <div class="comment" typeof="schema:UserComments">
  101. <p class="comment-meta">
  102. <span class="comment-author" property="schema:creator">NiCoS</span> le <span class="comment-date" property="schema:commentTime">24/04/2007</span> :
  103. </p>
  104. <div class="comment-content" property="schema:commentText">
  105. <p>Tip top !!<br />
  106. <br />
  107. ça répond à qqs questions que j'avais en tête et me fait découvrir des pans pas encore imaginés...<br />
  108. <br />
  109. Si seulement j'avais internet dans le RER, ça m'aiderait pour coder ;-D<br />
  110. <br />
  111. Vais presque pouvoir te &quot;piquer&quot; ton moteur de blog si ça continue :-P</p>
  112. </div>
  113. </div>
  114. <div class="comment" typeof="schema:UserComments">
  115. <p class="comment-meta">
  116. <span class="comment-author" property="schema:creator">vincent</span> le <span class="comment-date" property="schema:commentTime">26/04/2007</span> :
  117. </p>
  118. <div class="comment-content" property="schema:commentText">
  119. <p>En ce qui concenre django-openid, son code est déjà utilisable (google code hosting)..<br />
  120. <br />
  121. C'est un peu plus propre que ma version à moi :D</p>
  122. </div>
  123. </div>
  124. <div class="comment" typeof="schema:UserComments">
  125. <p class="comment-meta">
  126. <span class="comment-author" property="schema:creator">leau2001</span> le <span class="comment-date" property="schema:commentTime">14/02/2009</span> :
  127. </p>
  128. <div class="comment-content" property="schema:commentText">
  129. <p>Bonjour david,</p>
  130. <p>j&#39;ai essayé ton code : &quot;{% get_latest_objects journal.Post 5 as latest_posts %}<br />{% display_footer_posts %} &quot;</p>
  131. <p>voici comment : Je suis en train d&#39;essayer template_utils, mais je n&#39;y arrive pas :</p>
  132. <p>je fais ça :</p>
  133. <p><a href="http://www.friendpaste.com/7QtUTWQIPK1wOip3EAIyqc">http://www.friendpaste.com/7QtUTWQIPK1wOip3EAIyqc</a></p>
  134. <p>je pointe vers home.html et normalement je devrais avoir dans ma page mes titres de mes 5 derniers billets. mais hélas, je n&#39;ai que &quot;Derniers billets publiés&quot; qui s&#39;affiche, ou sont donc passés mes billets ? si tu as une idée, ça m&#39;aiderai beaucoup... merci</p>
  135. <p></p>
  136. </div>
  137. </div>
  138. </div>
  139. </section>
  140. <footer>
  141. <nav>
  142. <p>
  143. <small>
  144. Je réponds quasiment toujours aux <a href="m&#x61;ilto:d&#x61;vid%40l&#x61;rlet&#46;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>
  145. </small>
  146. </p>
  147. </nav>
  148. </footer>
  149. </div>
  150. <script src="/static/david/js/larlet-david-3ee43f.js" data-no-instant></script>
  151. <script data-no-instant>InstantClick.init()</script>
  152. </body>
  153. </html>