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.

article.md 6.6KB

title: Vues génériques, héritage et templatetags : développez rapidement avec Django slug: vues-generiques-heritage-et-templatetags-developpez-rapidement-avec-django date: 2007-04-24 08:48:42 type: post vignette: images/logos/biologeek.png contextual_title1: Biologeek (enfin) propulsé par Django contextual_url1: 20080423-biologeek-enfin-propulse-par-django contextual_title2: Ajout des flux RSS, du sitemap et des commentaires avec Django contextual_url2: 20070623-ajout-des-flux-rss-du-sitemap-et-des-commentaires-avec-django contextual_title3: De Dotclear à Django : migration des données et redirections contextual_url3: 20070523-de-dotclear-a-django-migration-des-donnees-et-redirections

Suite de la saga consacrée à la refonte de ce site. Aujourd'hui, on s'attaque à la partie visible de l'iceberg avec des petits raccourcis de Django qui changent la vie™.

URL et vues génériques

Les vues génériques sont issues d'un constat simple : beaucoup de sites sont destinés à afficher des informations au sujet d'une ressource ou à afficher une liste de ressources. C'est justement le cas des billets d'un blog donc on ne va pas s'en priver ! Par exemple si je considère ma ressource Post, je peux définir ma vue ainsi :

urlpatterns = patterns('django.views.generic.list_detail',
    (r'^([-\w]+,)*[-\w]+/(?P<slug>[-\w]+)/$',
        'object_detail',
        dict(
            queryset = Post.published.all(),
            template_object_name = 'post',
            slug_field='slug'
        )
    ),
)

L'expression régulière récupère ce qui est en /tag1,tag2/titre-du-billet/ et appelle la vue générique object_detail pour afficher le Post qui va matcher avec le slug (qui est le titre du billet sous forme d'URL). C'est tout simple et je n'ai plus qu'à me soucier du template associé pour afficher les informations souhaitées.

Dans le cas d'une agrégation de ressources (comme pour le journal par exemple), la définition ressemble à :

urlpatterns = patterns('django.views.generic.list_detail',
    (r'^journal/$',
        'object_list',
        dict(
            queryset = Post.published.all()[:10],
            template_object_name = 'post'
        )
    ),
)

Ici on appelle object_list pour afficher à l'URL /journal/ la liste des derniers billets publiés. Je préfère spécifier à chaque fois le template_object_name car j'aime bien savoir ce que je manipule dans les templates (par défaut le nom de la variable est object).

Comme vous pouvez le voir dans le fichier complet, un blog est défini en quelques lignes de code seulement... c'est toute la puissance de Django.

Héritage des templates

Une autre fonctionnalité qui permet de gagner énormément de temps. 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. 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 block.super ). J'ai du mal à expliquer clairement ce fonctionnement donc le mieux c'est peut-être d'aller lire le billet de Jeff Croft à ce sujet qui contient des exemples.

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 DRY à l'état pur.

Ces petits bouts de code...

... qui permettent de gagner du temps. Ils ont appelé ça templatetags 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 :

{% get_latest_objects journal.Post 5 as latest_posts %}
{% display_footer_posts %}

Le premier appel récupère les 5 objets de type Post et les place dans la variable latest_post. Le second est un inclusion tag 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 partagés donc c'est autant de code à produire en moins. À ce sujet, DjangoSnippets est une excellente ressource aussi.

J'espère que ces quelques exemples vous auront convaincu de la rapidité de développement avec Django (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 ;-)).

Prochaine étape : ma bête noire, la migration des données. C'est dommage car des solutions sont en train d'être mises en place 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 Django OpenID développé par Simon Willison (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.