Maîtrise des Modèles Django : Champs, Paramètres et Optimisation de Base de Données

Exploration des champs courants dans Django Models

L'ORM de Django propose une grande variété de types de champs pour structurer vos tables de base de données. Voici les plus fréquemment utilisés :

  • AutoField(primary_key=True) : Définit explicitement une clé primaire auto-incrémentée. Par défaut, Django crée un champ id si aucun n'est spécifié.
  • CharField(max_length=N) : Champ de texte court, équivalent au VARCHAR SQL.
  • IntegerField() et BigIntegerField() : Stockage d'entiers standards ou de grande taille (BIGINT).
  • DecimalField(max_digits=5, decimal_places=2) : Pour les nombres décimaux précis, idéal pour les données financières.
  • EmailField() : Une variante de CharField avec validation intégrée du format d'email.
  • DateField() et DateTimeField() :
    • auto_now : Met à jour la date automatiquement à chaque modification de l'objet.
    • auto_now_add : Enregistre la date de création de l'objet de manière immuable.
  • BooleanField() : Stocke des valeurs booléennes (True/False), converties en 0/1 au niveau de la base de données.
  • TextField() : Pour les longs blocs de texte sans limite de longueur stricte.
  • FileField(upload_to='media/') : Enregsitre le chemin du fichier dans la base de données et télécharge le fichier réel dans le répertoire spécifié.

Extension des types de champs : Création d'un champ CHAR fixe

Par défaut, CharField produit un VARCHAR. Pour utiliser un type CHAR de longueur fixe, on peut hériter de la classe de base Field.

from django.db import models

class CustomFixedCharField(models.Field):
    """
    Implémentation personnalisée pour le type SQL 'char'.
    """
    def __init__(self, size, *args, **kwargs):
        self.size = size
        super().__init__(max_length=size, *args, **kwargs)

    def db_type(self, connection):
        # Retourne le type de données SQL spécifique
        return 'char(%s)' % self.size

class Product(models.Model):
    serial_number = CustomFixedCharField(size=12)
    name = models.CharField(max_length=100)

Paramètres essentiels des champs

La configuration des champs peut être affinée via plusieurs arguments clés :

  • null=True : Autorise la base de données à stocker des valeurs vides (NULL).
  • default=value : Définit une valeur par défaut pour le champ.
  • unique=True : Garantit que chaque valeur dans cette colonne est unique à travers la table.
  • db_index=True : Crée un index sur la colonne pour accélérer les recherches.
  • on_delete : Depuis Django 2.0, ce paramètre est obligatoire pour les relations (ForeignKey, OneToOneField). models.CASCADE supprimera l'objet lié si l'objet parent est supprimé.

Supervision des requêtes SQL

Pour déboguer ou optimiser les performances, il est utile de voir les requêtes SQL générées par l'ORM dans la console. Ajoutez cette configuration dans votre fichier settings.py :

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'sql_console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['sql_console'],
            'propagate': True,
            'level': 'DEBUG',
        },
    }
}

Stratégies d'optimisation des requêtes (QuerySet)

L'optimisation des accès à la base de données est cruciale pour la rapidité de l'application.

1. Sélection de colonnes : only et defer

  • only('nom', 'prix') : Récupère uniquement les colonnes spécifiées. Si d'autres colonnes sont accédées plus tard, Django effectuera une nouvelle requête SQL (Lazy Loading).
  • defer('description') : Charge toutes les colonnes sauf celle spécifiée. Utile pour ignorer les champs lourds comme les TextField.

2. Optimisation des relations : select_related et prefetch_related

  • select_related : Réalise une jointure SQL (JOIN) lors de la requête initiale. Efficace pour les relations ForeignKey et OneToOne (côté "un").
  • prefetch_related : Effectue des requêtes SQL séparées et réalise la jointure au niveau de Python. Indispensable pour les realtions ManyToManyField et les relations inverses.

Le choix entre ces deux méthodes dépend de la structure des données et du volume d'enregistrements. En général, privilégiez select_related pour réduire le nombre de requêtes SQL totales lorsque c'est techniquement possible.

Étiquettes: django-models orm-optimization django-queryset python-backend sql-logging

Publié le 11 juillet à 23h05