La question du jour: qu’est-ce que l’objet context en Django


Petit mail aujourd’hui:

J’apprends Django. Pouvez-vous me dire ce qu’est l’object context dans une méthode liée à une vue. Je vois vaguement ce qu’est l’objet request mais pas l’objet context? pouvez-vous m’en dire plus?

L’objet context est ce qui permet de faire passer des valeurs depuis la vue au template.

Pour des raisons de performance, de sécurité et de facilité de débuggage, on ne veut pas passer toutes les variables d’une vue dans le template. On va donc créer un objet context, que l’on va remplir des trucs qu’on souhaite être accessibles depuis le template.

L’objet context ressemble à un dictionnaire: il a des clés et des valeurs. Il est d’ailleurs créé à partir d’un vrai dictionnaire, et la plupart du temps dans une vue on voit un truc comme ça:

tous_les_articles = Article.objects.all()
context = {'articles': tous_les_articles}
return render('index.html', context)

Typiquement cela veut dire “Renvoyer une réponse en utilisant le template index.html qui aura accès à la variable articles contenant des objets Article().).

Du coup, dans le template index.html, on pourra faire ça:

{{ articles }}

Mais pas ça:

{{ tous_les_articles }}

Car articles est dans le context, mais pas tous_les_articles. Même si dans notre cas on s’en branle puisqu’ils ont la même valeur.

Il y a un piège cependant dans cet exemple :-)

Context ici n’est PAS un objet context, mais par facilité on l’appelle ainsi. Ici context est un dictionnaire des valeurs que l’on veut mettre dans le vrai objet context. On passe ce dictionnaire à la fonction render() qui va se charger de la corvée de charger le template, créer le vrai objet context, lui passer les valeurs dans le dictionnaires, et faire le rendu du template avec ces valeurs puis retourner la réponse HTTP avec le résultat.

Je note que dans le question, notre interlocuteur nous parle de méthode. Si il utilise les vues génériques sous forme de classe (ce que je recommande d’éviter à tout prix), dans ce cas on retrouve le context généralement ainsi:

context = super(MaView, self).get_context_data(**kwargs)

Dans ce cas, context est le vrai objet context, déjà tout fait rien que pour vous par la vue. Mais comme il se comporte comme un dictionnaire, on peut très bien continuer à l’utiliser comme avant:

context['articles'] = Article.objects.all()
return context

Et du coup faire:

{{ articles }}

Dans le template spécifié dans l’attribut template_name de la classe.

Dans ce cas, la vue va se charger automatiquement de récupérer le context ainsi retourné, et de faire le rendu du template avec celui-ci. Ici ça à l’air un peu plus magique, et un débutant aura du mal à comprendre d’où vient le context et où va le context. C’est entre autre pour ça que je recommande de ne pas utiliser les vues sous forme de classe. Utilisez les fonctions, c’est beaucoup plus simple.

Une dernière chose: pourquoi utiliser un objet context, et pas juste un dictionnaire ? Après tout il s’agit juste d’avoir une liste des variables accessible dans le template non ?

En fait, le context peut faire bien plus. Notamment, il est possible de le remplir automatiquement pour toutes les vues au travers des context managers.

Par ailleurs, pour les questions sur Django, je vous recommande à tous de rejoindre le forum de Django-fr qui est justement là pour ça. On ouvrira un compte Sam&Max si personne ne répond :-)

4 thoughts on “La question du jour: qu’est-ce que l’objet context en Django

  • foxmask

    Bonjour

    Si il utilise les vues génériques sous forme de classe (ce que je recommande d’éviter à tout prix)

    quel est le problème avec les Classes Based Views ?

  • Sam Post author

    J’ai des classes bases views en prod depuis plus d’un an maintenant. Systématiquement: ça prend plus de temps à relire, à faire évoluer.

    Les débutants ne pigent rien et perdent des heures dessus (surtout que c’est la moins bonne partie de la doc Django).

    Il y a des bénéfices comme les mixins, mais par rapport au coût en temps, maintenance, complexité d’appropriation du code, ça ne compense pas.

    La dernière fois, un client m’a explicitement demandé de ne pas les utiliser parcequ’il trouvait que c’était trop relou pour son équipe après coup. J’ai réfléchi, et effectivement, vu que j’ai rien qui me manque dans les vues fonctions que j’ai dans les CBV, je me tiens à ça maintenant.

    Je ferais un article je crois :-)

  • foxmask

    ok. je le conçois. j’ai pas trouvé trop hard les CBV à partir du tuto ; on part de code qu’on recopie pour chaque fonction pour ensuite faire péter une CBV qui shoot tout ça avec la bonne magie du code ;)

    Puet-être que des CBV pour des choses hyper basiques (et performant) suffirait, sinon le faire classiquement avec des fonctions ? (article attendu ;)

Comments are closed.

Des questions Python sans rapport avec l'article ? Posez-les sur IndexError.