Mis a jour le 2025-04-14, 12:10

Mapping des URLs

Principe général :
  • on donne dans un fichier de conf python urls.py le mapping de chaque url (expression régulière) vers la view (vue) à utiliser.
  • exemple pour donner le mapping entre une url et une view à appeler :
    from django.conf.urls import url
    urlpatterns = [url('/monUrl/\d+$, views.myFunc),
                   url('/monUrl2/\d+$, views.myFunc2)]
        
  • les urls sont examinées une par une jusqu'à la première qui matche et qui est retenue.
  • l'examen des urls commence par le fichier myProject/urls.py, et en général, dans ce fichier, pour chaque application, il y a un include : url(r'^myAppUrl/', include('myApp.urls')) : toutes les urls qui commencent par myAppUrl/ sont alors aiguillées vers le fichier de mapping myApp/urls.py et myAppUrl/ est retiré de l'URL pour les matchs suivants.
  • la partie de l'URL qui est prise en compte pour le matching est celle en dehors du nom de machine et des arguments du GET (le ? et tout ce qui suit).
Capture des arguments à partir de l'expression régulière :
  • on peut faire des groupes non nommés : si l'expression régulière est ([^/]+)/([^/]+), alors la fonction view prend les arguments à la suite les uns des autres (le groupe matché par la première parenthèse, le groupe matché par la seconde parenthèse, ...). On peut les récupérer tous par : def myFunc(request, *args) (sous forme de liste dans args).
  • ou alors on peut faire des groupes nommés : si l'expression régulière est (?P<myVar1>[^/]+)/(?P<myVar2>[^/]+), alors la fonction view doit récupérer les variables myVar1, myVar2. On peut les récupérer tous par : def myFunc(request, **args) (sous forme de dictionnaire dans args).
  • si mélange de groupes nommés et non nommés, seul les groupes nommés sont pris en compte, les autres sont ignorés (les 2 modes sont exclusifs l'un de l'autre).
  • les arguments matchés sont toujours de type string (même si expression régulière comme \d+).
  • on peut passer un dictionnaire de paramètres supplémentaires après la vue :
    urlpatterns = [url('/monUrl/\d+$, views.myFunc, {'a': 1, 'b': 2})]
        
    • ces paramètres seront rajoutés à l'appel de fonction view.
    • en cas de conflit avec les paramètres nommés de l'expression régulière, c'est le dictionnaire qui prime.
    • si c'est un include, le dictionnaire est passé aux enfants.
  • le premier argument de patterns (souvent '') est en fait la chaîne de caractères à utiliser comme prefixe à tous les noms de views quand ils sont passés comme chaîne de caractères plutôt que comme fonction, ce qui n'est pas recommandé.
URL reversing :
  • mécanisme d'obtention d'une url à partir de certains éléments, c'est l'inverse de la résolution d'url et c'est défini dans le même fichier urls.py.
  • on suppose qu'on a défini comme pattern : url(r'^show/(\d{4})$', views.myFunc).
  • pour avoir cette url dans un template : {% url 'myApp.views.myFunc' myYear %} où la variable myYear contient le paramètre à utiliser pour le groupe défini dans l'expression régulière.
  • pour avoir cette url en utilisant du code python :
    from django.core.urlresolvers import reverse
    ...
       return HttpResponseRedirect(reverse('myApp.views.myFunc', args = (myYear, )))
        
    avec myYear la variable à utiliser à la place du groupe de l'expression régulière.
  • problème : si même view utilisée pour plusieurs urls (souvent le cas), pas possible de faire un reversing ! Solution : donner un nom aux urls :
    url(r'^show/(\d{4})$', views.myFunc, name = 'myUrlName')
        
    alors, le nom peut être utilisé dans un template directement : {% url 'myUrlName' myYear %} ou dans du code python : reverse('myUrlName', args = (myYear, )).
  • si les arguments sont nommés dans l'url :
    • url(r'^show/(?P<annee>\d{4})$', views.myFunc, name = 'myUrlName')
    • reverse('myUrlName', kwargs = {'annee': '2015'}).
Namespaces :
  • permettent d'utiliser les même noms d'urls dans différentes applications sans conflit.
  • lors de l'inclusion du fichier urls.py, déclarer un namespace : url(r'^myApp/', include('myApp.urls', namespace = 'myAppNs')).
  • puis, lors de l'utilisation de l'url, on préfixe avec le namespace : {% url 'myAppNs:myUrlName' %}

Copyright python-simple.com
programmer en python, tutoriel python, graphes en python, Aymeric Duclert