Vue d'ensemble
Django 2.0, publié le 2 décembre 2017, ouvre une nouvelle ère pour le framework en abandonnant définitivement Python 2. Sa nouveauté la plus visible est la fonction path() qui simplifie considérablement le routage d'URL en remplaçant les expressions régulières par des convertisseurs de type. Cette version apporte également une interface d'administration adaptée au mobile et les expressions Window.
Fonctionnalités principales
path() simplifie le routage URL
La fonction path() utilise des convertisseurs de type (int, str, slug, uuid) au lieu d'expressions régulières. L'ancienne fonction url() reste disponible sous le nom re_path() pour les cas nécessitant des regex.
from django.urls import path, re_path
from . import views
# Avant (Django 1.x) : expressions régulières obligatoires
# url(r'^articles/(?P<annee>[0-9]{4})/(?P<slug>[\w-]+)/$',
# views.detail_article),
# Après (Django 2.0) : convertisseurs de type lisibles
urlpatterns = [
path('articles/', views.liste_articles, name='liste'),
path('articles/<int:annee>/', views.par_annee, name='par_annee'),
path('articles/<int:annee>/<slug:slug>/', views.detail, name='detail'),
path('profil/<uuid:identifiant>/', views.profil, name='profil'),
# re_path pour les cas complexes
re_path(r'^archive/(?P<annee>[0-9]{4})-(?P<mois>[0-9]{2})/$',
views.archive_mensuelle),
]
Expressions Window
Les expressions Window permettent d'utiliser les fonctions fenêtrées SQL (ROW_NUMBER, RANK, LAG, LEAD) directement dans l'ORM Django. Elles sont particulièrement utiles pour les classements, les cumuls et les comparaisons entre lignes voisines.
from django.db.models import F, Window
from django.db.models.functions import Rank, RowNumber, Lag
# Classement des vendeurs par chiffre d'affaires
vendeurs = Vendeur.objects.annotate(
classement=Window(
expression=Rank(),
order_by=F('chiffre_affaires').desc(),
)
)
for v in vendeurs:
print(f"#{v.classement} {v.nom} : {v.chiffre_affaires} EUR")
# Comparaison avec la valeur précédente (ventes mensuelles)
ventes = VenteMensuelle.objects.annotate(
vente_precedente=Window(
expression=Lag('montant'),
order_by=F('mois').asc(),
)
)
