• 20 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 12/12/19

Passez des arguments à une vue

Log in or subscribe for free to enjoy all this course has to offer!

Dans le chapitre précédent vous avez ajouté deux vues : celle responsable de la page d'accueil et celle listant tous les albums. Nous verrons plus tard comment les améliorer pour les rendre inoubliables !

Dans ce chapitre nous allons nous intéresser à la transmission d'informations dans une requête. Il existe trois manières de le faire :

  • l'information se trouve dans le chemin de l'URL, par exemple /articles/145213-je-joue-du-banjo-et-j-adore-ca,

  • elle se trouve dans les paramètres d'une requête GET, par exemple /?query=bonjo. C'est exactement ce qui se produit lorsque vous entrez des valeurs dans un champ de recherche.

  • elle se trouve dans le corps d'une requête POST.

Dans ce chapitre, nous allons nous intéresser aux deux premières. D'ailleurs, je vous lance deux défis : créer deux nouvelles routes pour trouver des albums ! La première affichera les détails d'un album et la seconde les résultats d'un formulaire de recherche. A vos marques !

Afficher les détails d'un album

Afin d'afficher les artistes d'un album, il faut déjà le trouver ! Dans notre exemple, ALBUMS est une liste donc la méthode la plus simple est de trouver un album via son index. Comme ceci :

>>> ALBUMS[0]
{'name': 'Sarbacane', 'artists': [{'name': 'Francis Cabrel'}]}

En Python pur, c'est simple comme bonjour. Mais comment faire dans Django ? Vous allez simplement passer l'index en paramètre de la vue. Comme ceci :

views.py

def detail(request, album_id):
id = int(album_id) # make sure we have an integer.
album = ALBUMS[id] # get the album with its id.
artists = " ".join([artist['name'] for artist in album['artists']]) # grab artists name and create a string out of it.
message = "Le nom de l'album est {}. Il a été écrit par {}".format(album['name'], artists)
return HttpResponse(message)

Hé oui, une vue est avant tout une fonction ! Pas de magie ! :magicien:

D'ailleurs, il est temps de créer la route reliée à cette vue.

store/urls.py

urlpatterns = [
url(r'^$', views.listing),
url(r'^(?P<album_id>[0-9]+)/$', views.detail),
]

Ça se complique ! Peux-tu détailler l'expression régulière ?

Oui, bien sûr !

  • ^ : le schéma commence par le symbole qui suit. Chez nous il s'agit d'un groupe.

  • () : les parenthèses capturent un ensemble d'une expression régulière pour en faire un groupe distinct. Cela permet de le récupérer et de le manipuler sans se soucier du reste de l'expression.

  • ?P<album_id> : ici nous définissons le paramètre que nous souhaitons passer à la vue : album_id.

  • [0-9]+ : nous spécifions que nous attendons un ou plusieurs chiffres entre 0 et 9.

  • /$ : le motif termine par une barre oblique.

Ainsi, les URL suivantes correspondront à ce motif : /store/2/store/5, ... Les motifs d'URL sont simplement la forme générale d'une URL, par exemple /articles/2017/08/16.

Pour en savoir plus à ce sujet, lisez la partie dédiée aux URLs du tutoriel officiel

A présent, vérifiez que tout fonctionne : entrez l'url http://127.0.0.1:8000/store/2. Vous devriez voir le message attendu !

Afficher les résultats d'un formulaire de recherche

A présent, concentrons-nous sur l'URL reçue d'un formulaire de recherche. Imaginons l'URL suivante :

search/?query=Rosana

Comment y répondre ? Nous pourrions bien sûr créer une nouvelle route de la forme suivante :

'^search/\?query=(?P<query>[A-Z][a-z]+)/$'

Mais, vous vous en doutez, nous aurions de nouveaux soucis :

  • que se passe-t-il si l'utilisateur entre plusieurs termes dans le formulaire, générant une URL de la forme suivante : search/?query=Rosana&amp;María? Les caractères spéciaux à l'intérieur ne seront pas capturés.

  • Et si l'utilisateur entre des chiffres ? Eux non plus ne seront pas capturés.

  • Que se passe-t-il si l'URL ne contient aucune chaîne de caractères ? Le schéma ne sera pas reconnu.

Afin d'éviter cela, vous n'allez pas spécifier ces paramètres dans le schéma attendu. A l'inverse, vous les récupérerez dans la vue.

Créez une nouvelle route reliée à une nouvelle vue :

urls.py

urlpatterns = [
...
url(r'^search/$', views.search),
]

views.py

def search(request):
pass

L'objet request est une instance de la classe WSGIRequest qui a des propriétés tout à fait intéressantes, notamment GET qui renvoie un dictionnaire contenant les arguments passés à l'URL. Démonstration !

def search(request):
obj = str(request.GET)
query = request.GET['query']
message = "propriété GET : {} et requête : {}".format(obj, query)
return HttpResponse(message)

A présent, naviguez à l'url suivante : http://127.0.0.1:8000/store/search/?query=Lulu

La page affiche bien la requête passée en argument !

Nous n'avons plus qu'à l'utiliser pour trouver l'artiste correspondant dans le dictionnaire.

views.py

def search(request):
query = request.GET.get('query')
if not query:
message = "Aucun artiste n'est demandé"
else:
albums = [
album for album in ALBUMS
if query in " ".join(artist['name'] for artist in album['artists'])
]
if len(albums) == 0:
message = "Misère de misère, nous n'avons trouvé aucun résultat !"
else:
albums = ["<li>{}</li>".format(album['name']) for album in albums]
message = """
Nous avons trouvé les albums correspondant à votre requête ! Les voici :
<ul>
{}
</ul>
""".format("</li><li>".join(albums))
return HttpResponse(message)

Lancez les requêtes suivantes et admirez le résultat !

  • http://127.0.0.1:8000/store/search/?query=Ghost

  • http://127.0.0.1:8000/store/search/?query=Rosana

  • http://127.0.0.1:8000/store/search/

A ce stade, vous vous rendez certainement compte de plusieurs limites :

  • Il est très pénible de chercher des items imbriqués dans d'autres. J'ai personnellement l'impression de chercher une aiguille perdue au milieu de poupées russes.

  • Il est fastidieux d'ajouter des artistes à un album. De même, l'ajout d'un nouvel attribut à un album risquerait de casser notre code. Nous ne voulons pas cela !

  • Notre page HTML n'inclut, pour l'instant, que des éléments limités. Ajouter une feuille de style serait long et ennuyeux car il faudrait l'ajouter dans toutes les vues. Or, vous le savez bien, les développeurs détestent effectuer des tâches automatiques.

Vous vous doutez bien que Django vous apporte la solution à ces soucis sur un plateau d'argent ! Dans le chapitre suivant, vous découvrirez comment remplacer les constantes du fichier models.py par de vrais modèles reliés à une base de données. Vous avez hâte, n'est-ce pas ?!

Code du chapitre

Le code de ce chapitre est disponible à cette adresse.

Example of certificate of achievement
Example of certificate of achievement