Vue d'ensemble

Django 1.5, publié le 26 février 2013, est une version charnère du framework. Sa nouveauté principale est le modèle utilisateur personnalisable via le réglage AUTH_USER_MODEL, qui répond enfin à l'une des demandes les plus anciennes de la communauté. Cette version apporte également un support expérimental de Python 3 et les réponses en streaming.

Fonctionnalités principales

Modèle utilisateur personnalisable

Le réglage AUTH_USER_MODEL permet de remplacer le modèle User par défaut par un modèle entièrement personnalisé. On peut ainsi utiliser l'email comme identifiant principal, ajouter des champs métier dès la création du projet, ou adapter le modèle aux besoins spécifiques de l'application.

python
# settings.py
AUTH_USER_MODEL = 'comptes.Utilisateur'

# comptes/models.py
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.db import models

class GestionnaireUtilisateur(BaseUserManager):
    def create_user(self, email, mot_de_passe=None, **extras):
        if not email:
            raise ValueError("L'adresse email est obligatoire")
        utilisateur = self.model(
            email=self.normalize_email(email), **extras
        )
        utilisateur.set_password(mot_de_passe)
        utilisateur.save(using=self._db)
        return utilisateur

class Utilisateur(AbstractBaseUser):
    email = models.EmailField(unique=True)
    prenom = models.CharField(max_length=50)
    nom = models.CharField(max_length=50)
    est_actif = models.BooleanField(default=True)

    objects = GestionnaireUtilisateur()
    USERNAME_FIELD = 'email'

    def __str__(self):
        return self.email

Réponses en streaming

La classe StreamingHttpResponse permet d'envoyer une réponse HTTP par morceaux, sans charger la totalité du contenu en mémoire. C'est particulièrement utile pour l'export de gros fichiers CSV ou la génération de rapports volumineux.

python
import csv
from django.http import StreamingHttpResponse

def generer_lignes_csv(queryset):
    """Génère les lignes CSV une par une."""
    yield ['Nom', 'Email', 'Date inscription']
    for utilisateur in queryset.iterator():
        yield [
            utilisateur.nom,
            utilisateur.email,
            utilisateur.date_inscription.isoformat(),
        ]

class EcrivainCSV:
    """Adaptateur pour écrire du CSV en streaming."""
    def write(self, valeur):
        return valeur

def export_utilisateurs(request):
    queryset = Utilisateur.objects.all()
    ecrivain = csv.writer(EcrivainCSV())
    lignes = (ecrivain.writerow(ligne) for ligne in generer_lignes_csv(queryset))
    reponse = StreamingHttpResponse(lignes, content_type='text/csv')
    reponse['Content-Disposition'] = 'attachment; filename="utilisateurs.csv"'
    return reponse

Sources