gwift-book/chapters/urls.tex

107 lines
4.5 KiB
TeX
Raw Normal View History

2022-04-27 19:33:47 +02:00
\chapter{URLs et espaces de noms}
La gestion des URLs consiste \textbf{grosso modo} à assigner un chemin à une fonction Python.
\section{Configuration et correspondances}
2022-04-27 19:33:47 +02:00
2022-05-01 19:45:53 +02:00
La manière simple consiste à modifier le fichier \texttt{gwift/settings.py} pour y ajouter nos correspondances.
Par défaut, le fichier ressemble à ceci:
2022-04-27 19:33:47 +02:00
\begin{minted}{python}
# gwift/urls.py
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
]
\end{minted}
2022-05-01 19:45:53 +02:00
La variable \texttt{urlpatterns} associe un ensemble d'adresses à des fonctions.
Dans le fichier \textbf{nu}, seul le \textbf{pattern} \texttt{admin} est défini, et inclut toutes les adresses qui sont définies dans le fichier \texttt{admin.site.urls}.
2022-04-27 19:33:47 +02:00
2022-05-01 19:45:53 +02:00
Django fonctionne avec des \textbf{expressions rationnelles} simplifiées (des \textbf{expressions régulières} ou \textbf{regex}) pour trouver une correspondance entre une URL et la fonction qui recevra la requête et retournera une réponse.
Nous utilisons l'expression \texttt{\^{}\$} pour déterminer la racine de notre application, mais nous pourrions appliquer d'autres regroupements (\texttt{/home}, \texttt{users/\textless{}profile\_id\textgreater{}}, \texttt{articles/\textless{}year\textgreater{}/\textless{}month\textgreater{}/\textless{}day\textgreater{}}, \ldots\hspace{0pt}).
Chaque \textbf{variable} déclarée dans l'expression régulière sera apparenté à un paramètre dans la fonction correspondante. Ainsi, pour reprendre l'exemple où nous étions restés:
2022-04-27 19:33:47 +02:00
\begin{minted}{python}
# gwift/urls.py
from django.conf.urls import include, url
from django.contrib import admin
from wish import views as wish_views
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^$', wish_views.wishlists, name='wishlists'),
]
\end{minted}
2022-05-01 19:45:53 +02:00
Dans la mesure du possible, essayez toujours de \textbf{nommer} chaque expression.
Cela permettra notamment de les retrouver au travers de la fonction \texttt{reverse}, mais permettra également de simplifier vos templates.
2022-04-27 19:33:47 +02:00
2022-05-01 19:45:53 +02:00
A présent, on doit tester que l'URL racine de notre application mène bien vers la fonction \texttt{wish\_views.wishlists}.
2022-04-27 19:33:47 +02:00
2022-05-01 19:45:53 +02:00
Sauf que les pages \texttt{about} et \texttt{help} existent également. Pour implémenter ce type de précédence, il faudrait implémenter les URLs de la manière suivante:
2022-04-27 19:33:47 +02:00
\begin{verbatim}
| about
| help
| <user>
\end{verbatim}
2022-05-01 19:45:53 +02:00
Mais cela signifie aussi que les utilisateurs \texttt{about} et \texttt{help} (s'ils existent\ldots\hspace{0pt}) ne pourront jamais accéder à leur profil.
Une dernière solution serait de maintenir une liste d'authorité des noms d'utilisateur qu'il n'est pas possible d'utiliser.
2022-04-27 19:33:47 +02:00
2022-05-01 19:45:53 +02:00
D'où l'importance de bien définir la séquence de déinition de ces routes, ainsi que des espaces de noms.
2022-04-27 19:33:47 +02:00
Note sur les namespaces.
2022-05-01 19:45:53 +02:00
De là, découle une autre bonne pratique: l'utilisation de \emph{breadcrumbs} (\url{https://stackoverflow.com/questions/826889/how-to-implement-breadcrumbs-in-a-django-template}) ou de guidelines de navigation.
2022-04-27 19:33:47 +02:00
\section{Tests}
2022-04-27 19:33:47 +02:00
\subsection{Reverse}
2022-04-27 19:33:47 +02:00
2022-05-01 19:45:53 +02:00
En associant un nom ou un libellé à chaque URL, il est possible de récupérer sa \textbf{traduction}. Cela implique par contre de ne plus toucher à ce libellé par la suite\ldots\hspace{0pt}
2022-04-27 19:33:47 +02:00
2022-05-01 19:45:53 +02:00
Dans le fichier \texttt{urls.py}, on associe le libellé \texttt{wishlists} à l'URL \texttt{r\textquotesingle{}\^{}\$} (c'est-à-dire la racine du site):
2022-04-27 19:33:47 +02:00
\begin{minted}{python}
from wish.views import WishListList
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^$', WishListList.as_view(), name='wishlists'),
]
\end{minted}
2022-05-01 19:45:53 +02:00
De cette manière, dans nos templates, on peut à présent construire un lien vers la racine avec le tags suivant:
2022-04-27 19:33:47 +02:00
\begin{minted}{html}
<a href="{% url 'wishlists' %}">{{ yearvar }} Archive</a>
\end{minted}
2022-05-31 20:39:48 +02:00
De la même manière, on peut également récupérer l'URL de destination pour n'importe quel libellé, d'une des deux manières suivantes:
\begin{minted}{python}
from django.urls import reverse
wishlists_url = reverse('wishlists')
\end{minted}
2022-04-27 19:33:47 +02:00
\begin{minted}{python}
from django.core.urlresolvers import reverse_lazy
wishlists_url = reverse_lazy('wishlists')
\end{minted}
\subsection{Resolve}
La résolution d'une adresse consiste à retrouver la fonction à partir d'une URL.
Si nous donnons le chemin \texttt{/wishlists/wish/123}, nous nous attendons à recevoir la fonction en retour.
Au niveau des tests, cela permettra de nous assurer que c'est la bonne fonction qui est récupérée par une adresse connue.