Maîtriser Django QuerySets : un guide complet avec des exemples pratiques

Mastering Django QuerySets: A Comprehensive Guide with Practical Examples

Table of Contents

    Lorsque vous travaillez avec Django, il est essentiel de comprendre les QuerySets pour interagir efficacement avec votre base de données. Dans ce tutoriel, je vais vous expliquer les tenants et aboutissants des QuerySets à l'aide d'un modèle de contact simple. En cours de route, j'expliquerai ce que fait chaque commande, pourquoi elle est utile et comment vous pouvez l'appliquer à des scénarios réels. Si vous débutez avec Django ou si vous cherchez à améliorer vos compétences, vous êtes au bon endroit.

    Préparer le terrain : le modèle de contact

    Commençons par créer un petit modèle de contact. Imaginez que vous créez un carnet d'adresses dans lequel chaque contact possède un prénom, un nom et une adresse e-mail. Voici à quoi cela ressemble dans Django :

     from django.db import models class Contact(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) email = models.EmailField(unique=True) def __str__(self): return f"{self.first_name} {self.last_name}"

    Ce modèle est assez simple. Les champs first_name et last_name sont des CharFields d'une longueur maximale de 50 caractères, tandis que le champ email est unique, ce qui garantit l'absence d'adresses email en double. La méthode __str__ renvoie une belle représentation du contact, parfaite pour le débogage ou l'affichage de données.

    Exécutez vos migrations pour appliquer ce modèle à votre base de données :

     python manage.py makemigrations python manage.py migrate

    Le modèle étant prêt, plongeons dans les QuerySets.

    Qu'est-ce qu'un QuerySet ?

    Un QuerySet est essentiellement une collection de requêtes de base de données. Considérez-le comme un moyen de récupérer, de filtrer et de manipuler les données de votre base de données. La beauté des QuerySets est qu'ils sont paresseux, ce qui signifie qu'ils n'atteignent pas la base de données tant que vous ne les avez pas explicitement évalués. Cela les rend à la fois puissants et efficaces.

    Remplissons notre base de données avec quelques exemples de données avant d'explorer QuerySets.

    Ajout d'échantillons de données

    Lancez le shell Django pour créer des contacts :

     python manage.py shell

    À l'intérieur de la coque :

     from app.models import Contact Contact.objects.create(first_name="Alice", last_name="Smith", email="alice@example.com") Contact.objects.create(first_name="Bob", last_name="Jones", email="bob@example.com") Contact.objects.create(first_name="Charlie", last_name="Brown", email="charlie@example.com") Contact.objects.create(first_name="Diana", last_name="Prince", email="diana@example.com")

    Nous disposons désormais de données sur lesquelles travailler. Plongeons-nous dans QuerySets et voyons ce que nous pouvons faire.

    Récupération de tous les enregistrements

    Le QuerySet le plus simple est Contact.objects.all(). Il récupère tous les enregistrements de la table Contact.

     contacts = Contact.objects.all() print(contacts)

    Vous remarquerez qu'il ne récupère pas immédiatement les données, mais qu'il prépare simplement la requête. Il s'agit d'une excellente fonctionnalité de QuerySets, car elle évite les requêtes de base de données inutiles jusqu'à ce que vous ayez besoin des données.

    Pourquoi l'utiliser ?

    Si vous souhaitez voir tout ce qui se trouve dans votre tableau, all() est la solution idéale. C'est également le point de départ pour enchaîner d'autres commandes, que nous aborderons ensuite.

    Compter les enregistrements

    Vous voulez savoir combien de contacts vous avez ? Utilisez .count().

     count = Contact.objects.all().count() print(f"Total Contacts: {count}")

    Cela envoie une requête SELECT COUNT(*) à la base de données, ce qui est plus rapide que de charger tous les objets et de les compter en Python.

    Pourquoi l'utiliser ?

    Lorsque vous avez besoin d'un résumé rapide de vos données, le comptage des enregistrements est d'une valeur inestimable.

    Vérification de l'existence

    Si vous voulez simplement savoir si des enregistrements existent, .exists() est votre ami.

     exists = Contact.objects.all().exists() print(f"Contacts Exist: {exists}")

    C'est beaucoup plus rapide que de récupérer tous les enregistrements, car la recherche s'arrête dès qu'elle trouve la première correspondance.

    Pourquoi l'utiliser ?

    Idéal pour les scénarios tels que la logique conditionnelle : s'il y a des données, faites une chose ; sinon, faites autre chose.

    Récupération d'enregistrements spécifiques

    Parfois, vous savez exactement ce que vous cherchez. Utilisez .get() pour récupérer un seul enregistrement selon une condition spécifique :

     alice = Contact.objects.get(email="alice@example.com") print(f"Found Contact: {alice}")

    La prise

    • Si aucun enregistrement ne correspond, une exception DoesNotExist est générée.
    • Si plusieurs enregistrements correspondent, cela génère une exception MultipleObjectsReturned.

    Filtrage des données

    Et si vous voulez tous les contacts portant un nom de famille spécifique ? C'est là qu'intervient .filter().

     smith_contacts = Contact.objects.filter(last_name="Smith") print(smith_contacts)

    Cela crée un QuerySet de tous les enregistrements correspondants. Vous pouvez utiliser différentes recherches de champs pour affiner votre recherche :

    • icontains : Recherche insensible à la casse.
    • startswith : correspond au début d'une chaîne.
    • exact : correspond à la valeur exacte.

    Par exemple:

     emails_with_example = Contact.objects.filter(email__icontains="example.com")

    Pourquoi l'utiliser ?

    Le filtrage est l'une des opérations les plus courantes dans toute application basée sur une base de données. Il vous permet de vous concentrer sur les données dont vous avez besoin.

    Hors données

    Vous voulez tout sauf un ensemble spécifique d'enregistrements ? Utilisez .exclude() :

     non_smith_contacts = Contact.objects.exclude(last_name="Smith") print(non_smith_contacts)

    Classement des résultats

    Trier vos données est simple avec .order_by().

     ordered_contacts = Contact.objects.all().order_by("first_name") print(ordered_contacts)

    Pour trier par ordre décroissant, préfixez le champ avec un - :

     descending_contacts = Contact.objects.all().order_by("-last_name")

    Agrégations

    Si vous travaillez avec des données numériques, Django dispose de fonctions d'agrégation intégrées telles que Count , Sum , Avg , Max et Min . Comptons le nombre de noms de famille uniques que nous avons :

     from django.db.models import Count unique_last_names = Contact.objects.values("last_name").distinct().count() print(f"Unique Last Names: {unique_last_names}")

    Annotation des QuerySets

    Les annotations vous permettent d'ajouter des champs calculés à votre QuerySet. Par exemple, vous souhaiterez peut-être créer un champ full_name de manière dynamique :

     from django.db.models import Value from django.db.models.functions import Concat contacts = Contact.objects.annotate( full_name=Concat('first_name', Value(' '), 'last_name') ) for contact in contacts: print(contact.full_name)

    Résultats de découpage

    Vous avez besoin d'un sous-ensemble de vos données ? Utilisez le découpage :

     top_two_contacts = Contact.objects.all()[:2]

    SQL brut

    Si vous êtes curieux de savoir ce que Django fait sous le capot, vous pouvez inspecter le SQL brut :

     print(Contact.objects.all().query)

    Conclusion

    Les QuerySets de Django sont incroyablement puissants et leur maîtrise est un véritable atout pour travailler avec les données dans vos projets. Que vous filtriez des enregistrements, comptiez des lignes ou exécutiez des requêtes complexes, les QuerySets vous offrent les outils dont vous avez besoin pour effectuer le travail efficacement.

    En comprenant les bases et en vous plongeant dans des opérations plus avancées, vous serez en mesure d'écrire un code propre et optimisé qui tire pleinement parti de l'ORM de Django. Si vous avez trouvé ce guide utile, n'hésitez pas à le partager : il pourrait s'agir de la ressource que quelqu'un d'autre recherche !

    Published: 3 weeks, 5 days ago.