David Larlet : artisan, contributeur et citoyen.


Archives du site biologeek.com. Publications récentes.

Vues génériques, héritage et templatetags : développez rapidement avec Django

vignette

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.

Articles peut-être en rapport


Commentaires

NiCoS le 24/04/2007 :

Tip top !!

ça répond à qqs questions que j'avais en tête et me fait découvrir des pans pas encore imaginés...

Si seulement j'avais internet dans le RER, ça m'aiderait pour coder ;-D

Vais presque pouvoir te "piquer" ton moteur de blog si ça continue :-P

vincent le 26/04/2007 :

En ce qui concenre django-openid, son code est déjà utilisable (google code hosting)..

C'est un peu plus propre que ma version à moi :D

leau2001 le 14/02/2009 :

Bonjour david,

j'ai essayé ton code : "{% get_latest_objects journal.Post 5 as latest_posts %}
{% display_footer_posts %} "

voici comment : Je suis en train d'essayer template_utils, mais je n'y arrive pas :

je fais ça :

http://www.friendpaste.com/7QtUTWQIPK1wOip3EAIyqc

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'ai que "Derniers billets publiés" qui s'affiche, ou sont donc passés mes billets ? si tu as une idée, ça m'aiderai beaucoup... merci