URL e Routing
Il sistema di routing di Django mappa le URL alle views corrispondenti. Ogni richiesta HTTP viene analizzata dal URL dispatcher, che cerca una corrispondenza nella lista delle URL definite nel progetto e invoca la view associata.
Il File urls.py
Il file urls.py principale del progetto è il punto dâingresso per tutte le URL:
# miosito/urls.py
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
]
La lista urlpatterns contiene oggetti path() che definiscono le corrispondenze tra URL e views.
La Funzione path()
path() accetta i seguenti argomenti:
from django.urls import path
from . import views
urlpatterns = [
# path(route, view, kwargs=None, name=None)
path('', views.home, name='home'),
path('chi-siamo/', views.chi_siamo, name='chi-siamo'),
path('contatti/', views.contatti, name='contatti'),
]
- route: La stringa URL da abbinare.
- view: La funzione view da chiamare.
- kwargs: Argomenti aggiuntivi da passare alla view (opzionale).
- name: Nome univoco per riferirsi allâURL nel codice e nei template.
Parametri nelle URL
Django supporta parametri dinamici nelle URL usando le parentesi angolari:
urlpatterns = [
# Parametro intero
path('articolo/<int:id>/', views.dettaglio, name='dettaglio'),
# Parametro stringa
path('categoria/<str:nome>/', views.categoria, name='categoria'),
# Parametro slug
path('post/<slug:slug>/', views.post, name='post'),
# Parametro UUID
path('ordine/<uuid:codice>/', views.ordine, name='ordine'),
]
I convertitori di tipo disponibili sono:
str: Qualsiasi stringa non vuota (esclude/). Predefinito.int: Un numero intero positivo.slug: Lettere, numeri, trattini e underscore.uuid: Un UUID formattato.path: Qualsiasi stringa, incluso/.
La view riceve i parametri come argomenti:
def dettaglio(request, id):
articolo = Articolo.objects.get(pk=id)
return render(request, 'dettaglio.html', {'articolo': articolo})
La Funzione re_path()
Per pattern URL complessi, usa re_path() con espressioni regolari:
from django.urls import re_path
urlpatterns = [
re_path(r'^articoli/(?P<anno>[0-9]{4})/$', views.per_anno),
re_path(r'^articoli/(?P<anno>[0-9]{4})/(?P<mese>[0-9]{2})/$', views.per_mese),
]
re_path() usa la sintassi delle regex Python. I gruppi nominali (?P<nome>pattern) vengono passati come argomenti alla view.
Include: Organizzare le URL per App
La funzione include() permette di delegare la gestione delle URL a file separati per ogni app:
# miosito/urls.py (progetto principale)
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')),
path('api/', include('api.urls')),
path('utenti/', include('utenti.urls')),
]
# blog/urls.py
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path('', views.lista, name='lista'),
path('<slug:slug>/', views.dettaglio, name='dettaglio'),
path('nuovo/', views.crea, name='crea'),
]
Namespace delle URL
La variabile app_name definisce il namespace dellâapp, utile per evitare conflitti tra URL con lo stesso nome in app diverse:
# blog/urls.py
app_name = 'blog'
urlpatterns = [
path('', views.lista, name='lista'),
]
Per riferirsi a una URL con namespace nel codice o nei template:
# Nel codice Python
from django.urls import reverse
url = reverse('blog:lista')
url_dettaglio = reverse('blog:dettaglio', kwargs={'slug': 'mio-articolo'})
<!-- Nei template -->
<a href="{% url 'blog:lista' %}">Tutti gli articoli</a>
<a href="{% url 'blog:dettaglio' slug=articolo.slug %}">Leggi</a>
La Funzione reverse()
reverse() genera una URL a partire dal suo nome, utile nelle views e nei test:
from django.urls import reverse
def crea_articolo(request):
# Dopo aver salvato l'articolo...
url = reverse('blog:dettaglio', args=[articolo.slug])
return redirect(url)
reverse() solleva unâeccezione NoReverseMatch se il nome dellâURL non viene trovato, aiutando a individuare errori di configurazione.
Conclusione
Il sistema di routing di Django è potente e flessibile. Lâuso di path() per le URL semplici, include() per organizzare le URL per app e i namespace per evitare conflitti sono pratiche essenziali per un progetto ben strutturato. La funzione reverse() garantisce che i link nel codice restino validi anche quando le URL cambiano.