Un système d’URLs propre, élégant, est un aspect important dans une application Web de qualité. Django vous permet de concevoir vos URL de la façon qui vous convient le mieux, sans limitations dues au framework.
Vous n’aurez pas l’obligation d’insérer .php ou .cgi dans une URL, et encore moins ce type d’absurdités :
0,2097,1-1-1928,00.
Consultez Cool URIs don’t change, par Tim Berners-Lee, le créateur du World Wide Web, pour une excellente argumentation expliquant pourquoi les URLs doivent être propres et utilisables.
Pour créer les URLs d’une application, vous créez un module Python appelé URLconf (URL configuration). Ce module n’est rien d’autre que du code Python pur et il consiste en une cartographie de motifs d’URL sous forme d’expressions rationnelles (URL patterns) vers des fonctions callback Python (vos vues).
Cette cartographie est aussi courte ou aussi longue que nécessaire. Elle peut se référer à d’autres cartographies. Et, comme il s’agit de code Python pur, elle peut être construite dynamiquement.
Lorsqu’un utilisateur demande une page, voici l’algorithme suivi par le système pour déterminer quel code Python exécuter:
ROOT_URLCONF , mais si l’objet HttpRequest entrant a un attribut appelé urlconf (paramétré par le
middleware request processing), sa valeur sera utilisée à la place du paramètre ROOT_URLCONF.urlpatterns. Il s’agit d’une liste Python, au format retourné par la fonction django.conf.urls.patterns().HttpRequest en premier argument et toute valeur capturée par l’expression rationnelle en arguments suivants.Voici un échantillon d’URLconf:
from django.conf.urls import patterns, url, include
urlpatterns = patterns('',
(r'^articles/2003/$', 'news.views.special_case_2003'),
(r'^articles/(\d{4})/$', 'news.views.year_archive'),
(r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
)
Notes:
^articles, pas ^/articles.'r' au début de chaque expression rationnelle est facultatif mais conseillé. Il dit à Python qu’une chaîne est “brute” (“raw”) – que rien dans la chaîne ne doit être échappé. Voir Dive Into Python.Exemple de requêtes:
/articles/2005/03/ correspondra à la troisième entrée de la liste. Django appellera la fonction
news.views.month_archive(request, '2005', '03')./articles/2005/3/ ne correspondra à aucun des motifs d’URL, parce que la troisième entrée de la liste requiert 2 chiffres pour le mois./articles/2003/ correspondra au premier motif de la liste, pas au second, parce que les motifs sont testés dans l’ordre, et le premier est le premier à réussir le test. N’hésitez pas à exploiter l’ordre pour insérer des cas particuliers comme celui-ci./articles/2003 ne correspondra à aucun de ces motifs, parce que chaque motif exige que l’URL se termine par un slash./articles/2003/03/03/ correspondra au dernier motif. Django appellera la fonction news.views.article_detail(request, '2003', '03', '03').Pour capturer les parties de l’URL et les passer en arguments positionnels à une vue, l’exemple précédent utilise des groupes d’expressions rationnelles simples, non nommées (via des parenthèses). Dans une utilisation plus avancée, il est possible d’utiliser des groupes d’expressions rationnelles nommés pour capturer des parties d’URL et les passer à une vue en tant qu’arguments mots-clé.
Dans les expressions rationnelles Python, la syntaxe pour les groupes nommés d’expressions rationnelles est (?P<name>pattern), où name est le nom du groupe et pattern est le motif à rechercher.
Voici le précédent exemple URLconf, ré-écrit pour utiliser les groupes nommés:
urlpatterns = patterns('',
(r'^articles/2003/$', 'news.views.special_case_2003'),
(r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'news.views.month_archive'),
(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/$', 'news.views.article_detail'),
)
Ce code exécute exactement la même chose que l’exemple précédent, avec une différence subtile: les valeurs capturées sont passées aux fonctions vues comme arguments mots-clés plutôt que comme arguments positionnels. Par exemple:
/articles/2005/03/ appellera la fonction
news.views.month_archive(request, year='2005', month='03'), au lieu de news.views.month_archive(request, '2005', '03')./articles/2003/03/03/ appellera la fonction
news.views.article_detail(request, year='2003', month='03', day='03').En pratique, cela veut dire que vos URLconfs sont légèrement plus explicites et moins sujets à des bugs relatifs à l’ordre des arguments – et vous pouvez réordonner les arguments dans vos déclarations de fonctions vue. Bien sûr, ces avantages se font aux dépens de la concision; certains développeurs trouvent la syntaxe groupes nommées laide et trop bavarde.
Voici l’algorithme que le parseur URLconf suit, par rapport aux groupes nommés vs groupes non nommés d’une expression rationnelle:
S’il trouve des arguments nommés, il les utilisera et ignorera les arguments non nommés. Sinon, il passera tous les arguments non nommés en tant qu’arguments positionnels.
Dans les deux cas, il passera tout argument mot-clé supplémentaire comme argument mot-clé. Voir Passer des options supplémentaires aux fonctions vue ci-dessous.
URLconf fait sa recherche sur l’URL demandée, en tant que chaîne Python normale. Cela ne concerne pas les paramètres GET ou POST, ou le nom de domaine.
Par exemple, dans une requête http://www.example.com/myapp/, URLconf cherchera myapp/.
Sur une requête pour http://www.example.com/myapp/?page=3, URLconf cherchera myapp/.
URLconf ne regarde pas la méthode de requête. En d’autres termes, toutes les méthodes de requêtes – POST, GET, HEAD, etc. – de la même URL seront dirigées vers la même fonction.
urlpatterns doit être une liste Python, au format retourné par la fonction django.conf.urls.patterns(). Utilisez toujours patterns() pour créer la variable urlpatterns.
django.conf.urls¶Deprecated since version 1.4: A partir de Django 1.4 les fonctions patterns, url, include et les symboles handler* décrits ci-dessous se trouvent dans le module django.conf.urls.
Jusqu’à Django 1.3 ils étaient situés dans django.conf.urls.defaults. Vous pouvez encore les importer depuis ce module mais ils disparaîtront dans Django 1.6.
patterns(prefix, pattern_description, ...)¶Une fonction qui prend un préfixe et un nombre quelconque de motifs d’URL, et retourne une liste de de motifs d’URL dans un format requis par Django.
Le premier argument de patterns() est une chaîne prefix. Voir
Le préfixe de vue plus loin.
Les arguments restants doivent être des tuples dans ce format:
(regular expression, Python callback function [, optional dictionary [, optional name]])
...où optional dictionary et optional name sont optionnels. (Voir
Passer des options supplémentaires aux fonctions vue ci-dessous.)
Note
Parce que patterns() est un appel de fonction, il accepte un maximum de 255 arguments (des motifs d’URL dans le cas présent). C’est une limitation des appels de fonction Python. En pratique, c’est rarement un problème parce que vous structurerez vos motifs d’URL modulairement en utilisant des sections include(). Cependant, si par miracle vous atteignez la limite des 255 arguments, sachez que patterns() renvoie une liste Python, vous pouvez donc diviser la construction de la liste.
urlpatterns = patterns('',
...
)
urlpatterns += patterns('',
...
)
Les listes Python ont une taille illimitée, il n’y a donc pas de limite au nombre de motifs d’URL que vous pouvez construire. La seule limite est que vous ne pouvez en créer que 254 à la fois (le 255e argument est l’argument prefix initial).
url(regex, view, kwargs=None, name=None, prefix='')¶Vous pouvez utiliser la fonction url(), au lieu d’un tuple, en tant qu’argument pour
patterns(). C’est pratique si vous voulez spécifier un nom sans le dictionnaire d’arguments supplémentaires optionnels. Par exemple:
urlpatterns = patterns('',
url(r'^index/$', index_view, name="main-view"),
...
)
Cette fonction prend cinq arguments, la plupart sont optionnels:
url(regex, view, kwargs=None, name=None, prefix='')
Voir Nommer les motifs d’URL pour savoir pourquoi le paramètre name est utile.
Le paramètre prefix a le même sens que le premier argument pour
patterns() et il n’est pertinent que lorsque vous passez une chaîne comme paramètre view.
include(<module or pattern_list>)¶Une fonction qui prend un chemin d’import Python complet vers un autre module URLconf qui doit être “inclus” à cet endroit.
include() accepte également comme argument un itérable qui renvoie URL
patterns.
Voir Inclure d’autres URLconfs ci-dessous.
Lorsque Django ne peut trouver une expression rationnelle correspondant à l’URL demandée, ou lorsque une exception est levée, Django invoquera une vue gestionnaire d’erreur. Les vues à utiliser dans ces cas-là sont spécifiées par trois variables qui peuvent être initialisées dans votre URLconf racine. Initialiser ces variables dans n’importe quel autre URLconf sera sans effet.
Voir la documentation sur customizing error views pour plus de détails.
handler403¶Un appelable, ou une chaîne représentant le chemin d’import Python complet sur la vue devant être appelée si l’utilisateur n’a pas les droits requis pour accéder à une ressource.
Par défaut, il s’agit de 'django.views.defaults.permission_denied'. Cette valeur par défaut devrait faire l’affaire.
Voir la documentation sur the 403 (HTTP Forbidden) view plus pour d’informations.
handler403 est nouveau dans Django 1.4.handler404¶Un appelable, ou une chaîne représentant le chemin complet d’import Python sur la vue devant être appelée si aucun des motifs URL ne correspond.
Par défaut, il s’agit de 'django.views.defaults.page_not_found'. Cette valeur par défaut devrait faire l’affaire.
handler500¶Un appelable, ou une chaîne représentant le chemin d’import Python complet sur la vue devant être appelée en cas d’erreurs serveurs. Les erreurs serveurs se produisent lorsque vous avez des erreurs d’exécution dans le code vue.
Par défaut, il s’agit de 'django.views.defaults.server_error'. Cette valeur par défaut devrait faire l’affaire.
Chaque argument capturé est envoyé à la vue en tant que texte Python simple, indépendamment du type de correspondance que font les expressions rationnelles. Par exemple, dans cette ligne URLconf:
(r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
...l’argument year pour news.views.year_archive() sera une chaîne, pas un entier, même si \d{4} ne correspond qu’à des entiers sous forme de chaîne.
Un truc commode est de spécifier les paramètres par défaut pour vos arguments de vues. Voici un exemple URLconf et vue:
# URLconf
urlpatterns = patterns('',
(r'^blog/$', 'blog.views.page'),
(r'^blog/page(?P<num>\d+)/$', 'blog.views.page'),
)
# View (in blog/views.py)
def page(request, num="1"):
# Output the appropriate page of blog entries, according to num.
Dans cet exemple, les deux motifs URL pointent vers la même vue –
blog.views.page – mais le premier motif ne capture rien de l’URL. Si le premier motif correspond, la fonction page() utilisera son argument par défaut pour num, "1". Si le deuxième motif correspond, page() utilisera n’importe quel valeur num capturée par l’expression rationnelle.
Chaque expression rationnelle d’un urlpatterns est compilé lors de son premier accès. Cela rend le système fougueusement rapide.
Vous pouvez spécifier un préfixe commun à votre appel de patterns(), pour réduire la duplication de code.
Voici l’exemple URLconf de Django overview:
from django.conf.urls import patterns, url, include
urlpatterns = patterns('',
(r'^articles/(\d{4})/$', 'news.views.year_archive'),
(r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
)
Dans cet exemple, chaque vue a un préfixe commun – 'news.views'.
Au lieu de le retaper pour chaque entrée dans urlpatterns, vous pouvez utiliser le premier argument de la fonction patterns() pour spécifier un préfixe à appliquer à chaque fonction vue.
Avec cela, l’exemple précédent s’écrira de manière plus concise:
from django.conf.urls import patterns, url, include
urlpatterns = patterns('news.views',
(r'^articles/(\d{4})/$', 'year_archive'),
(r'^articles/(\d{4})/(\d{2})/$', 'month_archive'),
(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'article_detail'),
)
Notez que vous ne mettez pas de point final (".") au préfixe. Django le fait automatiquement.
En pratique, vous finirez probablement par mélanger différents types de vues, au point qu’elles n’auront pas de préfixe commun dans votre urlpatterns. Vous pouvez cependant continuer à tirer partie du raccourci par le préfixe pour les vues pour éviter la duplication de code. Ajoutez simplement plusieurs objets patterns() ensemble, comme ceci:
Avant:
from django.conf.urls import patterns, url, include
urlpatterns = patterns('',
(r'^$', 'django.views.generic.date_based.archive_index'),
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'django.views.generic.date_based.archive_month'),
(r'^tag/(?P<tag>\w+)/$', 'weblog.views.tag'),
)
Après:
from django.conf.urls import patterns, url, include
urlpatterns = patterns('django.views.generic.date_based',
(r'^$', 'archive_index'),
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$','archive_month'),
)
urlpatterns += patterns('weblog.views',
(r'^tag/(?P<tag>\w+)/$', 'tag'),
)
À tout moment, votre urlpatterns peut “inclure” d’autres modules URLconf. This
essentially “roots” a set of URLs below other ones.
Par exemple, voici un extrait de l’URLconf du Django Web site. Il inclut un certain nombre d’autres URLconfs:
from django.conf.urls import patterns, url, include
urlpatterns = patterns('',
# ... snip ...
(r'^comments/', include('django.contrib.comments.urls')),
(r'^community/', include('django_website.aggregator.urls')),
(r'^contact/', include('django_website.contact.urls')),
(r'^r/', include('django.conf.urls.shortcut')),
# ... snip ...
)
Notez que les expressions rationnelles de cet exemple n’ont pas de $
(caractère de fin de ligne ) mais incluent un slash de fin. Chaque fois que
Django rencontre include(), il coupe les parties de l’URL qui correspondaient à ce stade et envoie la chaîne restante à l’URLconf inclue pour la suite du traitement.
Une autre possibilité est d’inclure les motifs d’URL supplémentaires non pas en spécifiant le module Python URLconf qui les définit en argument pour include mais en utilisant directement la liste de motifs telle qu’elle est renvoyée par patterns. Par exemple:
from django.conf.urls import patterns, url, include
extra_patterns = patterns('',
url(r'^reports/(?P<id>\d+)/$', 'credit.views.report', name='credit-reports'),
url(r'^charge/$', 'credit.views.charge', name='credit-charge'),
)
urlpatterns = patterns('',
url(r'^$', 'apps.main.views.homepage', name='site-homepage'),
(r'^help/', include('apps.help.urls')),
(r'^credit/', include(extra_patterns)),
)
Vous pouvez voir une utilisation de cette approche lorsque vous déployez une instance de l’application Django
Admin. Django Admin est déployée en tant qu’instance de AdminSite; chaque instance
AdminSite a un attribut urls qui renvoie le motif d’url disponible pour cette instance. C’est cet attribut que vous include() dans vos projets urlpatterns lorsque vous déployez l’instance admin.
Un URLconf inclus reçoit n’importe quel paramètre capturé des URLconfs parents, aussi, l’exemple suivant est valable:
# Dans settings/urls/main.py
urlpatterns = patterns('',
(r'^(?P<username>\w+)/blog/', include('foo.urls.blog')),
)
# Dans foo/urls/blog.py
urlpatterns = patterns('foo.views',
(r'^$', 'blog.index'),
(r'^archive/$', 'blog.archive'),
)
Dans cet exemple, la variable capturée "username" est passée à l’URLconf inclus, comme attendu.
Lorsque vous devez déployer de multiples instances d’une seule application, il peut s’avérer pratique de pouvoir les différencier les unes des autres. C’est particulièrement important avec l’utilisation de Nommer les motifs d’URL, puisque de multiples instances d’une même application partageront les URLs nommées. Les espaces de noms fournissent un moyen de désigner ces URLs nommées à part.
Un espace de nom URL est composé de deux parties, toutes deux étant des chaînes:
admin.admin.Les espaces de nom URL peuvent être déclarés de deux façons.
En premier lieu, vous pouvez fournir les espaces de nom application et instances en argument à include() lorsque vous construisez vos motifs d’URL. Par exemple:
(r'^help/', include('apps.help.urls', namespace='foo', app_name='bar')),
Cela inclut les URLs déclarées dans apps.help.urls à l’intérieur de l’espace de nom application bar, avec l’espace de nom instance foo.
Deuxièmement, vous pouvez inclure un objet qui contient des données espaces de nom embarquées. Si vous include() un objet patterns, cet objet sera ajouté à l’espace de nom global. Vous pouvez cependant aussi include() un objet qui contient un 3-tuple contenant:
(<patterns object>, <application namespace>, <instance namespace>)
Cela incluera les motifs d’URL désignés à l’intérieur de l’application donnée et l’espace de nom instance. Par exemple, l’attribut urls de l’objet AdminSite de Django retourne un 3-tuple qui contient tous les motifs d’un site admin, plus le nom de l’instance admin, et l’espace de nom application admin.
Une fois que les espaces de nom URL sont déclarés, vous pouvez les inverser. Pour des détails sur l’inversion de l’espace de nom URL, voir la documentation inverser les espaces de nom URLs.
Les URLconfs ont un hook qui vous permet de passer des arguments supplémentaires à vos fonctions vues, via un dictionnaire Python.
Chaque tuple URLconf peut avoir un troisième élément optionnel, qui doit être un dictionnaire d’arguments mot-clé à passer à la fonction vue.
Par exemple:
urlpatterns = patterns('blog.views',
(r'^blog/(?P<year>\d{4})/$', 'year_archive', {'foo': 'bar'}),
)
Dans cet exemple, pour une requête vers /blog/2005/, Django appelera la vue
blog.views.year_archive(), en lui passant ces arguments mot-clé:
year='2005', foo='bar'
Cette technique est utilisée dans generic views et dans le syndication framework pour passer des metadata et des options aux vues.
Gérer les conflits
Il est possible d’avoir un motif d’URL qui capture les arguments mot-clé nommés, et passe également des arguments avec les même noms dans ses dictionnaires d’arguments supplémentaires. Quand cela arrive, les arguments dans le dictionnaire seront utilisés à la place des arguments capturés dans l’URL.
include()¶De même, vous pouvez passer des options supplémentaires à include(). Lorsque vous le faites, chaque ligne de l’URLconf inclus recevra les options supplémentaires.
Par exemple, ces deux paramétrages URLconf sont fonctionnellement identiques:
Paramétrage n° 1:
# main.py
urlpatterns = patterns('',
(r'^blog/', include('inner'), {'blogid': 3}),
)
# inner.py
urlpatterns = patterns('',
(r'^archive/$', 'mysite.views.archive'),
(r'^about/$', 'mysite.views.about'),
)
Paramétrage n° 2:
# main.py
urlpatterns = patterns('',
(r'^blog/', include('inner')),
)
# inner.py
urlpatterns = patterns('',
(r'^archive/$', 'mysite.views.archive', {'blogid': 3}),
(r'^about/$', 'mysite.views.about', {'blogid': 3}),
)
Notez que les options supplémentaires seront toujours passées à chaque ligne de l’URLconf inclus, sans tenir compte du fait que la vue ligne accepte réellement ces options comme valides. Pour cette raison, cette technique n’est utile que si vous êtes certains que chacune des vues de l’URLconf accepte les options supplémentaires que vous passez.
Quelques développeurs trouvent plus naturel de passer la vraie fonction objet Python plutôt qu’une chaîne contenant le chemin vers son module. Cette possibilité est prise en charge – vous pouvez passez n’importe quel objet appelable en tant que vue.
Par exemple, en passant cette URLconf en notation “chaîne”:
urlpatterns = patterns('',
(r'^archive/$', 'mysite.views.archive'),
(r'^about/$', 'mysite.views.about'),
(r'^contact/$', 'mysite.views.contact'),
)
Vous pouvez faire la même chose en passant des objets plutôt que des chaînes. Assurez-vous simplement d’importer les objets:
from mysite.views import archive, about, contact
urlpatterns = patterns('',
(r'^archive/$', archive),
(r'^about/$', about),
(r'^contact/$', contact),
)
L’exemple suivant est fonctionnellement identique. Il est juste un peu plus compact car il importe le module qui contient les vues, au lieu d’importer chaque vue individuellement:
from mysite import views
urlpatterns = patterns('',
(r'^archive/$', views.archive),
(r'^about/$', views.about),
(r'^contact/$', views.contact),
)
Vous êtes libre d’utiliser le style que vous préférez.
Notez que si vous utilisez cette technique – passer des objets plutôt que des chaînes – le préfixe vue (expliqué plus haut dans Le préfixe de vue) n’aura pas d’effet.
Il est assez courant d’utiliser la même fonction vue dans plusieurs motifs URL de votre URLconf. Par exemple, ces deux motifs URL pointent les deux vers la vue archive:
urlpatterns = patterns('',
(r'^archive/(\d{4})/$', archive),
(r'^archive-summary/(\d{4})/$', archive, {'summary': True}),
)
C’est totalement valide mais amènera à des problèmes lorsque vous tenterez d’inverser la correspondance d’URL (via le décorateur permalink() ou le tag de template url). Avec cet exemple, si vous voulez récupérer l’URL de la vue archive, Django sera désorienté parce que deux motifs d’URL pointent sur cette vue.
Pour résoudre la question, Django prend en charge les motifs d’URL nommés. Vous donnez un nom à un motif d’URL pour le différencier d’autres motifs utilisant la même vue et les mêmes paramètres. Ensuite, vous utiliserez ce nom dans la recherche inverse d’URL.
Voici l’exemple précédent, réécrit pour utiliser les motifs d’URL nommés:
urlpatterns = patterns('',
url(r'^archive/(\d{4})/$', archive, name="full-archive"),
url(r'^archive-summary/(\d{4})/$', archive, {'summary': True}, "arch-summary"),
)
Avec ces noms (full-archive et arch-summary), vous pouvez cibler chaque motif individuellement en utilisant son nom:
{% url arch-summary 1945 %}
{% url full-archive 2007 %}
Même si ici les deux motifs d’URL se réfèrent à la vue archive, utiliser le paramètre
nom dans url() vous permet de les différencier dans les templates.
La chaîne utilisée pour le nom d’URL contient n’importe quel caractère. Vous n’êtes pas limité aux noms Python valides.
Note
Lorsque vous nommez vos motifs d’URL, assurez-vous d’utiliser un nom qui ne risque pas de se télescoper avec des noms utilisés par d’autres applications. Si vous appelez votre motif d’URL comment, et qu’une autre application fait la même chose, il n’y a aucune garantie sur l’URL qui sera insérée dans votre template lorsque vous utiliserez ce nom.
Ajouter un préfixe à vos noms d’URL, qui pourrait être dérivé du nom de l’application, diminuera les risques de collisions. Nous conseillons quelque chose comme myapp-comment plutôt que comment.
Les espaces de nommage d’URLs sont spécifiés en utilisant l’opérateur :. Par exemple, la page index principale de l’application admin est référencée en utilisant admin:index. Cela désigne l’espace de nom admin, et l’URL nommée index.
Les espaces de noms peuvent également être imbriqués. L’URL nommée foo:bar:whiz cherchera un nom de motif whiz dans l’espace de nom bar qui est lui-même déclaré dans l’espace de nom foo de premier niveau.
Avec un espace de nom URL donné à résoudre (par exemple, myapp:index), Django divisera le nom qualifié complet en plusieurs parties, et esaiera les recherches suivantes:
D’abord, Django cherchera un espace de nom d’une application (myapp dans cet exemple). Cela fournira une liste d’instances de cette application.
S’il y a une application en cours déclarée, Django cherchera et renverra le résolveur d’URL pour cette instance. L’application en cours peut être déclarée en tant qu’attribut du contexte de template - les applications susceptibles d’avoir de multiples déploiements devraient paramétrer l’attribut current_app pour tout Context ou RequestContext qui est utilisé pour rendre un template.
L’application en cours peut aussi être manuellement spécifiée en tant qu’argument de la fonction reverse().
S’il n’y a pas d’application en cours. Django cherche une instance d’application par défaut. L’instance d’application par défaut est l’instance qui a une instance d’espace de nom correspondant à l’espace de nom de l’application (dans cet exemple, une instance de myapp appelée myapp).
S’il n’y a pas d’instance d’application par défaut, Django choisira la dernière instance d’application déployée, quel que soit le nom de cette instance.
Si l’espace de nom fourni ne correspond pas à un espace de nom d’application du point 1, Django essaiera une recherche directe de l’espace de nom en tant qu’instance d’espace de nom.
S’il existe des espaces de nom imbriqués, ces étapes sont répétées pour chaque partie de l’espace de nom jusqu’à ce que seul le nom de la vue ne soit pas résolue. Le nom de la vue sera alors résolu dans une URL de l’espace de nom trouvé.
Pour montrer le fonctionnement de cette stratégie, étudions un exemple de deux instances de myapp: une appelée foo, et une autre appelée bar. myapp a une page index principale avec une URL nommée index. Avec ce paramètrage, les recherches suivantes sont possibles:
bar - myapp:index résoudra la page index de l’instance bar.myapp:index résoudra vers la dernière instance enregistrée de myapp. Puisqu’il n’y a pas d’instance par défaut, la dernière instance de myapp enregistrée sera utilisée. Ce pourra être foo ou bar, selon l’ordre dans lequel ils ont été présentés dans l’urlpatterns du projet.foo:index résoudra toujours vers la page index de l’instance foo.S’il y avait aussi une instance par défaut - c’est à dire une instance nommée myapp - voici ce qui se passera:
bar - myapp:index résoudra la page index de l’instance bar.myapp:index résoudra vers la dernière instance enregistrée de myapp.foo:index résoudra à nouveau vers la page index de l’instance foo.django.core.urlresolvers utility functions¶Si dans votre code vous devez utiliser quelque chose qui ressemble à la balise de template url, Django fournit cette fonction (dans le module django.core.urlresolvers):
reverse(viewname[, urlconf=None, args=None, kwargs=None, current_app=None])¶viewname est soit le nom de la fonction (soit une référence de fonction, ou la version chaîne du nom, si vous avez utilisé cette forme dans urlpatterns) soit le URL pattern name. Normalement vous n’aurez pas à vous préoccuper du paramètre urlconf et vous passerez seulement les arguments mots-clés et positionnels à utiliser dans la correspondance d’URL. Par exemple:
from django.core.urlresolvers import reverse
def myview(request):
return HttpResponseRedirect(reverse('arch-summary', args=[1945]))
La fonction reverse() peut inverser une grande variété d’expressions rationnelles pour les URLs, mais pas toutes celles qui sont possibles. la principale contrainte pour le moment est que le motif ne peut pas contenir de choix alternatifs en utilisant le caractère barre verticale ("|") . Vous pouvez utiliser avec bonheur ces motifs pour la correspondance des URLs et leur envoi vers les vues, mais vous ne pouvez pas inverser ces motifs.
L’argument current_app vous permt de fournir un indice au résolveur en indiquant l’application à laquelle appartient la vue en cours d’exécution. L’argument current_app est utilisé comme indice pour résoudre l’espace de nom de l’application en URLs d’une instance d’application spécifique, en accord avec Espaces de nom URL.
Vous pouvez utiliser kwargs au lieu de args. Par exemple:
>>> reverse('admin:app_list', kwargs={'app_label': 'auth'})
'/admin/auth/'
args et kwargs ne peuvent pas être passés à reverse() en même temps.
Soyez sûrs que toutes vos vues sont correctes.
Pour déterminer quels noms d’URL correspondent à quels motifs, la fonction
reverse() doit importer tous vos fichiers URLconf et examiner le nom
de chaque vue. Cela implique d’importer chaque fonction vue. S’il y a une
quelconque erreur lors de l’import des fonctions vue, reverse()
lèvera une erreur, même si la fonction vue en question n’est pas celle que
vous essayiez d’inverser.
Assurez-vous que les vues référencées dans vos fichiers URLconf existent et peuvent être importées correctement. Ne mettez pas de lignes qui référencent des vues qui ne sont pas encore écrites, car ces vues ne seront pas importables.
Note
La chaîne renvoyée par reverse() est déjà
urlquoted. Par exemple:
>>> reverse('cities', args=[u'Orléans'])
'.../Orl%C3%A9ans/'
Appliquer un encodage supplèmentaire (comme urlquote() ou
urllib.quote) au retour de reverse()
peut produire des résultats indésirables.
Une version paresseuse de reverse().
reverse_lazy(viewname[, urlconf=None, args=None, kwargs=None, current_app=None])¶C’est utile lorsque vous avez besoin d’utiliser une inversion URL avant que l’URLconf du votre projet soit chargé. Quelques cas habituels pour lesquels cette fontion est nécessaire:
url d’une vue générique class-based.login_url pour le décorateur
django.contrib.auth.decorators.permission_required()).La fonction django.core.urlresolvers.resolve() peut être utilisée pour résoudre les chemins d’URL aux fonctions vue correspondantes. Sa signature est la suivante:
resolve(path, urlconf=None)¶path est le chemin d’URL à résoudre. Comme avec
reverse(), vous n’avez pas à vous préoccuper du paramètre urlconf. La fonction retourne un objet
ResolverMatch qui vous permet d’accèder à différents meta-data sur l’URL résolue.
Si l’URL ne résout pas, la fonction lève une exception Http404.
ResolverMatch¶func¶La fonction vue à utiliser pour servir l’URL
args¶Les arguments à passer à la fonction vue, comme parsés depuis l’URL.
kwargs¶Les arguments mot-clé à passer à la fonction vue, comme parsés depuis l’URL.
url_name¶Le nom du motif URL qui correspond à l’URL.
app_name¶L’espace de nom de l’application du motif URL qui correspond à l’URL.
namespace¶L’espace de nom de l’instance du motif URL qui correspond à l’URL.
namespaces¶La liste des composants individuels d’espace de nom dans l’instance complète d’espace de nom pour le motif d’URL qui correspond à l’URL, c’est à dire, si l’espace de nom est foo:bar, alors les espaces de nom seront ['foo', 'bar'].
Un objet ResolverMatch peut être interrogé pour fournir des infos sur le motif d’URL qui correspond à l’URL:
# Resolve a URL
match = resolve('/some/path/')
# Print the URL pattern that matches the URL
print match.url_name
Un objet ResolverMatch peut aussi être assigné à un triple:
func, args, kwargs = resolve('/some/path/')
resolve() renvoyait un
triple contenant (view function, arguments, keyword arguments);
l’objet ResolverMatch (ainsi que l’espace de nom et les infos motif qu’il fournit) n’est pas disponible dans les récentes versions de Django.Une utilisation possible de resolve() est de tester si une vue pourrait lever une erreur Http404 avant d’être redirigé vers elle:
from urlparse import urlparse
from django.core.urlresolvers import resolve
from django.http import HttpResponseRedirect, Http404
def myview(request):
next = request.META.get('HTTP_REFERER', None) or '/'
response = HttpResponseRedirect(next)
# modify the request and response as required, e.g. change locale
# and set corresponding locale cookie
view, args, kwargs = resolve(urlparse(next)[2])
kwargs['request'] = request
try:
view(*args, **kwargs)
except Http404:
return HttpResponseRedirect('/')
return response
Le décorateur django.db.models.permalink() sert à écrire des méthodes courtes qui retournent un chemin d’URL complet. Par exemple, une méthode de modèle get_absolute_url(). Voir django.db.models.permalink() pour d’autres infos.
get_script_prefix()¶Normalement, vous devriez toujours utiliser reverse() ou
permalink() pour déclarer des URLs dans votre application.
Cependant, si votre application construit elle-même une partie de la hiérarchie URL, vous
aurez occasionnellement besoin de générer les URLs. Dans ce cas, vous devrez être capable de trouver l’URL de base du projet Django dans le serveur Web (normalement, reverse() s’en occupe pour vous ). Dans ce cas, vous pouvez appler get_script_prefix(), qui vous retournera la partie préfixe de script de l’URl de votre projet Django. Si votre projet Django
est à la racine du serveur Web, c’est toujours "/", mais cela peut être modifié, par exemple, en utilisant django.root (voir How to use Django with Apache and mod_python).
Aug 13, 2017