Tutos Django

Django shortcuts - Raccourcis

Vous avez pu remarquer au cours des derniers tutoriaux que nous avons utilisé différentes façons de retourner de la donnée depuis notre contrôleur vers nos vues.
Par exemple dans le tutoriel sur les formulaires, nous avons utilisé le raccourci 'render_to_response' dans le contrôleur 'views.py' mais nous aurions pu utiliser d'autres raccourcis.

Rappelons d'abord comment un contrôleur le plus simple qu'il soit peut s'écrire :

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello, world.")

Nous faisons appel à la méthode HttpResponse du module http pour ensuite retourner une chaîne de caractère. Et nous ne faisons pas appel à un template !
Django n'est en effet pas un FrameWork MVC (Modèle/Vue/Contrôleur) comme les autres. Puisque vous aurez remarquez que le "contrôleur" est nommé "views" et que les "vues" sont nommées "templates". En réalité, c'est moi-même qui ai choisi de faire ces propres associations afin de faciliter la compréhension du framework. Pour ceux qui veulent en savoir plus sur le type de framework qu'est réellement Django, je vous conseille cette lecture de la documentation officielle : Django appears to be a MVC framework

Cependant ne vous inquiétez pas, la logique que nous avons suivi jusqu'à présent a été celle d'un framework MVC classique mais vous savez à présent que Django est plus que cela ;) un "MTV" : "model", "template", et "view."
Je parlerai dès à présent uniquement de "view" et de "template" et non plus de "contrôleur" et "vue" pour éviter toute confusion possible.

Si nous voulons utiliser un template couplé à notre view, nous pouvons écrire :

from django.template import Context, loader
from users.models import User
from django.http import HttpResponse

def index(request):
    users_list = User.objects.all()
    t = loader.get_template('users/index.html')
    c = Context({
        'users_list': users_list,
    })
    return HttpResponse(t.render(c))

On importe les modules Context et loader ainsi qu'un modèle que nous avons déjà défini, ici User.
La fonction 'index' de notre view va récupérer une liste d'objets 'User' pour ensuite les passer au template 'index.html' contenu dans le dossier 'users'.

Cependant ceci est assez verbeux, et heureusement pour nous des raccourcis django existent tels que render_to_response, le code précédent peut alors s'écrire de cette façon :

from django.shortcuts import render_to_response
from users.models import User
def index(request):
    users_list = User.objects.all()
    return render_to_response('users/index.html', {'users_list': users_list})

Plus agréable n'est-ce pas ? ;)
Notez que le second argument "le contexte" représenté par un dictionnaire est optionnel. De plus render_to_response peut prendre deux autres arguments optionnels : 'context_instance' et 'mimetype'. Le code précédent aurait pu être écrit de cette façon :

from django.shortcuts import render_to_response
from django.template import RequestContext
from users.models import User
def index(request):
    users_list = User.objects.all()
    return render_to_response('users/index.html', {'users_list': users_list}, context_instance=RequestContext(request), mimetype="application/xhtml+xml")

Rappelez-vous d'ailleurs qu'il est très important de spécifier le 'context_instance' pour une view retournant un formulaire utilisant la protection 'csrf_token' sans quoi une erreur serait affichée. En effet, le contexte de la requête n'est pas retourné par défaut avec render_to_response, et notre template a besoin de certaines informations du contexte pour fonctionner dans ce cas précis.
Pour plus d'informations sur render_to_response, reportez-vous à la documentation officielle : render_to_response

Pour être sûr d'utiliser un context_instance qui utilise RequestContext, le raccourci 'render' existe et possède en plus deux arguments optionnels :  'status' et 'current_app'. On peut alors écrire :

from django.shortcuts import render
from users.models import User
def my_view(request):
    users_list = User.objects.all()
    return render(request, 'users/index.html', {'users_list': users_list},
        content_type="application/xhtml+xml")

Ce qui au final sera équivalent à :

from django.http import HttpResponse
from django.template import RequestContext, loader
from users.models import User

def my_view(request):
    users_list = User.objects.all()
    t = loader.get_template('users/index.html')
    c = RequestContext(request, {'users_list': users_list})
    return HttpResponse(t.render(c),
        content_type="application/xhtml+xml")

Le passage de données et de contexte doit maintenant être bien plus clair pour vous ;)
Pour plus d'informations sur render, reportez-vous à la documentation officielle : render

Un autre raccourci bien pratique est 'redirect' qui permet de rediriger vers une autre URL. Il peut prendre en principal argument trois types différents :

  • Un modèle : La fonction get_absolute_url() du modèle sera appelée.
  • Le nom d'une vue, avec la possibilité de lui passer des arguments: urlresolvers.reverse() sera utilisé pour résoudre-inversement le nom.
  • Une URL, qui sera utilisée pour la redirection.

Ainsi que la possibilité de passer un second argument optionnel 'permanent' qui par défaut est à False, ce qui définira si la redirection doit être considérée comme permanente ou temporaire.
Pour plus d'informations sur redirect et des cas d'utilisations, reportez-vous à la documentation officielle : redirect

get_object_or_404 et get_list_or_404 sont deux raccourcis très intéressants qui vont permettre de gérer la propagation d'une erreur de type 404 dans le cas où un objet demandé ou une liste d'objets demandée ne sont pas trouvés. Exemple :

from django.shortcuts import get_object_or_404

def my_view(request):
    my_object = get_object_or_404(MyModel, pk=1)

serait équivalent à :

from django.http import Http404

def my_view(request):
    try:
        my_object = MyModel.objects.get(pk=1)
    except MyModel.DoesNotExist:
        raise Http404

de même que :

from django.shortcuts import get_list_or_404

def my_view(request):
    my_objects = get_list_or_404(MyModel, published=True)

serait équivalent à :

from django.http import Http404

def my_view(request):
    my_objects = list(MyModel.objects.filter(published=True))
    if not my_objects:
        raise Http404

Voilà ! Grâce aux raccourcis que nous venons de voir, vous pouvez à présent faciliter l'écriture de votre code et le maintenir plus facilement !
Il peut également être intéressant de jeter un coup d'œil à HttpResponse sur la documentation officielle où une pléthore d'informations est disponible pour correctement gérer les fonctions de votre view : HttpResponse

Article suivant

Article précédent

Articles associés

Articles similaires

Commentaires

Les commentaires sont fermés.

Pingbacks

Les pingbacks sont fermés.