logo oujood
🔍

Les QuerySets Django

Un QuerySet est une collection d'objets issus de la base de données. Django construit et exécute les requêtes SQL en arrière-plan — vous travaillez uniquement avec des objets Python. Ce chapitre couvre les méthodes essentielles pour récupérer, filtrer, trier et limiter vos données.

OUJOOD.COM

Qu'est-ce qu'un QuerySet

Un QuerySet est une liste d'objets du modèle Django, construite à partir de la base de données. Il est paresseux (lazy) : Django ne déclenche pas la requête SQL au moment où vous définissez le QuerySet, mais seulement quand vous accédez réellement aux données — en itérant dessus, en l'affichant, ou en appelant certaines méthodes. Cette mécanique évite les requêtes inutiles.

Tous les QuerySets partent du gestionnaire objects attaché à chaque modèle.

Récupérer tous les enregistrements

all() retourne un QuerySet contenant tous les objets d'une table :

  📋 Copier le code

from .models import Membres

# Retourne tous les membres
membres = Membres.objects.all()

# Itérer sur le QuerySet
for m in membres:
    print(m.prenom, m.nom)

Filtrer avec filter()

filter() retourne un QuerySet contenant uniquement les objets qui correspondent aux conditions passées. Il s'utilise avec des lookups — des suffixes qui précisent le type de comparaison.

  📋 Copier le code

# Égalité exacte
Membres.objects.filter(nom='Refsnes')

# Contient (insensible à la casse)
Membres.objects.filter(prenom__icontains='em')

# Commence par
Membres.objects.filter(nom__startswith='R')

# Supérieur à (sur un champ numérique)
Membres.objects.filter(age__gt=30)

# Dans une liste de valeurs
Membres.objects.filter(nom__in=['Refsnes', 'Dubois', 'Morin'])

Les lookups les plus courants :

__exact / __iexact — égalité exacte, sensible ou non à la casse.

__contains / __icontains — contient la chaîne, sensible ou non à la casse.

__startswith / __endswith — commence ou finit par.

__gt / __gte / __lt / __lte — supérieur, supérieur ou égal, inférieur, inférieur ou égal.

__in — présent dans une liste.

__isnull — valeur nulle ou non (True / False).

Exclure avec exclude()

exclude() est l'inverse de filter() — il retourne les objets qui ne correspondent pas à la condition :

  📋 Copier le code

# Tous les membres sauf ceux dont le nom est 'Refsnes'
Membres.objects.exclude(nom='Refsnes')

# Enchaînement : filtrer puis exclure
Membres.objects.filter(prenom__startswith='E').exclude(nom='Refsnes')

Récupérer un seul objet avec get()

get() retourne un seul objet correspondant à la condition. Si la condition retourne zéro ou plusieurs objets, Django lève une exception — c'est son comportement intentionnel.

  📋 Copier le code

# Récupère le membre avec id=1
membre = Membres.objects.get(id=1)
print(membre.prenom)  # Emil

# Protection contre les erreurs
try:
    membre = Membres.objects.get(id=99)
except Membres.DoesNotExist:
    print("Membre introuvable")

get() est réservé aux cas où vous êtes certain qu'il existe exactement un résultat — typiquement une recherche par clé primaire. Pour tout autre cas, utilisez filter().

Trier avec order_by()

order_by() trie le QuerySet selon un ou plusieurs champs. Un tiret devant le nom du champ inverse l'ordre :

  📋 Copier le code

# Ordre alphabétique par nom
Membres.objects.all().order_by('nom')

# Ordre alphabétique inverse
Membres.objects.all().order_by('-nom')

# Tri sur plusieurs champs : d'abord par nom, puis par prénom
Membres.objects.all().order_by('nom', 'prenom')

Limiter les résultats

Django supporte le découpage de QuerySet (slicing) comme une liste Python, sans charger tous les résultats en mémoire :

  📋 Copier le code

# Les 5 premiers membres
Membres.objects.all()[:5]

# Du 6ème au 10ème
Membres.objects.all()[5:10]

# Le premier résultat (retourne un objet ou None)
Membres.objects.filter(nom='Dubois').first()

# Le dernier résultat
Membres.objects.all().order_by('id').last()

Compter et vérifier l'existence

  📋 Copier le code

# Nombre total de membres
Membres.objects.count()

# Nombre de membres dont le nom commence par R
Membres.objects.filter(nom__startswith='R').count()

# Vérifier si au moins un résultat existe
Membres.objects.filter(nom='Refsnes').exists()  # True ou False

Enchaîner les méthodes

Les QuerySets sont chaînables — chaque méthode retourne un nouveau QuerySet. Vous pouvez combiner autant de filtres que nécessaire :

  📋 Copier le code

# Membres dont le prénom contient 'a', triés par nom, 10 premiers
Membres.objects.filter(prenom__icontains='a').order_by('nom')[:10]

Par carabde | Mis à jour le 05 mai 2025