# Documentation Django 5.2.8

# Options `Meta` des modèles

Ce document explique toutes les options de métadonnées qu’il est possible d’attribuer aux modèles dans leur classe `Meta` interne.

## Options `Meta` disponibles

### `abstract`

Options.abstract

  Si `abstract = True`, ce modèle sera une classe de base abstraite.

### `app_label`

Options.app_label

  Si un modèle est défini en dehors d’une application dans `INSTALLED_APPS`, il doit déclarer à quelle application il appartient :

      app_label = "myapp"

  Si vous souhaitez représenter un modèle avec le format `étiquette_app.nom_objet` ou `étiquette_app.nom_modèle`, vous pouvez respectivement utiliser `model._meta.label` ou `model._meta.label_lower`.

### `base_manager_name`

Options.base_manager_name

  Le nom d’attribut du gestionnaire à utiliser pour l’attribut `_base_manager` du modèle, par exemple `'objects'`.

### `db_table`

Options.db_table

  Le nom de la table de base de données à utiliser pour le modèle :

      db_table = "music_album"

#### Noms de tables

Pour vous faire gagner du temps, Django dérive automatiquement le nom de la table de base de données du nom de la classe de modèle et de l’application dans laquelle elle se trouve. Un nom de table de base de données d’un modèle est construit en adjoignant le « label » d’application du modèle (le nom utilisé lors de la commande `manage.py startapp`) au nom de classe du modèle, combinés par un soulignement.

Par exemple, pour une application `bibliotheque` (qui serait créée avec `manage.py startapp bibliotheque`) et un modèle défini par `class Livre`, le nom de la table de base de données serait `bibliotheque_livre`.

Pour surcharger le nom de la table de base de données, utilisez l’attribut `db_table` de la classe `Meta`.

Si votre nom de table de base de données est un mot SQL réservé ou s’il contient des caractères non autorisés dans des noms de variables Python (en particulier le trait d’union), il n’y a pas de souci à se faire. Django place entre guillemets les noms de colonnes et de tables en arrière-plan.

Noms de tables en minuscules pour MariaDB et MySQL

Il est fortement conseillé d’écrire les noms de tables en minuscules lors de leur surcharge avec `db_table`, particulièrement lorsqu’on utilise le moteur MySQL. Voir les notes pour MySQL pour plus de détails.

Noms de tables entre guillemets pour Oracle

Afin de respecter la limite de 30 caractères qu’Oracle impose aux noms de tables et pour suivre les conventions habituelles des bases de données Oracle, Django peut raccourcir les noms de tables et les transformer en majuscules. Pour empêcher ces transformations, écrivez des valeurs entre guillemets dans `db_table`:

    db_table = '"name_left_in_lowercase"'

Il est aussi possible d’utiliser de tels noms entre guillemets avec les autres moteurs de base de données pris en charge par Django ; cependant, contrairement à Oracle, les guillemets n’ont pas d’effet. Voir les notes sur Oracle pour plus de détails.

### `db_table_comment`

Options.db_table_comment

Le commentaire sur la table de base de données à utiliser pour ce modèle. C’est utile pour documenter les tables de base de données pour ceux qui ont un accès direct à la base de données et qui ne lisent pas forcément votre code Django. Par exemple

    class Answer(models.Model):
        question = models.ForeignKey(Question, on_delete=models.CASCADE)
        answer = models.TextField()

        class Meta:
            db_table_comment = "Question answers"

### `db_tablespace`

Options.db_tablespace

  Le nom de l’espace de tables de base de données à utiliser pour ce modèle. La valeur par défaut est le réglage `DEFAULT_TABLESPACE` du projet, s’il est défini. Si le moteur ne prend pas en charge les espaces de tables, cette option est ignorée.

### `default_manager_name`

Options.default_manager_name

  Le nom du gestionnaire à utiliser pour l’attribut `_default_manager` du modèle.

### `default_related_name`

Options.default_related_name

  Le nom qui sera utilisé par défaut pour la relation depuis un objet lié vers cet objet. La valeur par défaut est `<nom_modèle>_set`.

  Cette option définit également `related_query_name`.

  Comme le nom inverse d’un champ doit être unique, faites attention si vous créez une sous-classe du modèle. Pour contourner les collisions de noms, une partie du nom devrait contenir `'%(app_label)s'` et `'%(model_name)s'`, qui sont respectivement remplacés par le nom de l’application contenant le modèle, et le nom du modèle, les deux en minuscules. Consultez le paragraphe sur les noms de liaison des modèles abstraits.

### `get_latest_by`

Options.get_latest_by

  Le nom d’un champ ou une liste de noms de champs du modèle, typiquement un champ `DateField`, `DateTimeField` ou `IntegerField`. Cette option définit le ou les champs par défaut à utiliser dans les méthodes `latest()` et `earliest()` du gestionnaire (`Manager`) du modèle.

  Exemple :

      # Latest by ascending order_date.
      get_latest_by = "order_date"

      # Latest by priority descending, order_date ascending.
      get_latest_by = ["-priority", "order_date"]

  Voir la documentation de `latest()` pour plus de détails.

### `managed`

Options.managed

  La valeur par défaut est `True`, signifiant que Django crée les tables de base de données adéquates dans `migrate` ou dans le cadre des migrations et les efface dans le contexte de la commande d’administration `flush`. C’est-à-dire que Django pilote le cycle de vie des tables de la base de données.

  Si la valeur est `False`, aucune opération de création, de modification ou de suppression de table de base de données n’est effectuée pour ce modèle. Utile si le modèle représente une table existante ou une vue de base de données qui a été créée par un autre moyen. C’est l’unique différence lorsque `managed=False`. Tous les autres aspects de la gestion des modèles sont traités comme pour un modèle normal. Cela inclut :

  1. Adding an automatic primary key field to the model if you don’t declare it. To avoid confusion for later code readers, it’s recommended to specify all the columns from the database table you are modeling when using unmanaged models.

  2. Si un modèle avec `managed=False` contient un champ `ManyToManyField` qui pointe vers un autre modèle non piloté, la table intermédiaire de la relation plusieurs-à-plusieurs ne sera pas non plus créée. Cependant, la table intermédiaire entre un modèle piloté et un modèle non piloté sera bel et bien créée.

     Si vous aimeriez changer ce comportement par défaut, créez explicitement le modèle de la table intermédiaire (avec l’option `managed` appropriée) et utilisez l’attribut `ManyToManyField.through` pour que la relation utilise le modèle ainsi créé.

  En ce qui concerne les tests impliquant des modèles avec `managed=False`, c’est à vous de vous assurer que les tables correctes soient créées dans le cadre de la mise en place des tests.

  Si vous êtes intéressé à modifier le comportement Python d’une classe de modèle, vous pourriez utiliser `managed=False` et créer une copie d’un modèle existant. Cependant, il existe une meilleure approche pour ce genre de situation : Modèles mandataires.

### `order_with_respect_to`

Options.order_with_respect_to

  Rend cet objet « triable » en fonction du champ donné, presque toujours un champ `ForeignKey`. Cela peut être utilisé pour permettre à des objets liés d’être triés en fonction d’un objet parent. Par exemple, si un objet `Answer` (réponse) est lié à un objet `Question` et qu’une question possède plus d’une réponse et que l’ordre des réponses est signifiant, voici comment cela serait défini :

      from django.db import models

      class Question(models.Model):
          text = models.TextField()
          # ...

      class Answer(models.Model):
          question = models.ForeignKey(Question, on_delete=models.CASCADE)
          # ...

          class Meta:
              order_with_respect_to = "question"

  Lorsque `order_with_respect_to` est défini, deux méthodes complémentaires sont fournies pour récupérer et définir l’ordre des objets liés : `get_RELATED_order()` et `set_RELATED_order()`, où `RELATED` est le nom du modèle en minuscules. Par exemple, en supposant qu’un objet `Question` possède plusieurs objets `Answer` liés, la liste renvoyée contient les clés primaires des objets `Answer` liés :

      >>> question = Question.objects.get(id=1)
      >>> question.get_answer_order()
      [1, 2, 3]

  L’ordre des objets liés `Answer` d’un objet `Question` peut être défini en passant une liste de clés primaires d’objets `Answer`:

      >>> question.set_answer_order([3, 1, 2])

  Les objets liés reçoivent aussi deux méthodes, `get_next_in_order()` et `get_previous_in_order()`, qui peuvent être utilisées pour accéder à ces objets dans l’ordre correct. En supposant que les objets `Answer` sont triés par `id`:

      >>> answer = Answer.objects.get(id=2)
      >>> answer.get_next_in_order()
      <Answer: 3>
      >>> answer.get_previous_in_order()
      <Answer: 1>

`order_with_respect_to` définit implicitement l’option `ordering`.

En interne, `order_with_respect_to` ajoute un champ (colonne de base de données) supplémentaire nommé `_order` et définit l’option `ordering` du modèle avec ce champ. Par conséquent, `order_with_respect_to` et `ordering` ne peuvent pas être utilisés conjointement, et l’ordre de tri ajouté par `order_with_respect_to` s’applique chaque fois que vous obtenez une liste d’objets pour ce modèle.

Modification de `order_with_respect_to`

Comme `order_with_respect_to` ajoute une colonne de base de données supplémentaire, il vous revient donc de créer et d’appliquer les migrations appropriées si vous ajoutez ou modifiez `order_with_respect_to` après la création initiale opérée par `migrate`.

### `ordering`

Options.ordering

  Le tri par défaut des objets, lors de l’obtention de listes d’objets :

      ordering = ["-order_date"]

  Il s’agit d’un tuple ou d’une liste de chaînes, ou d’expressions de requête. Chaque chaîne correspond à un nom de champ, facultativement préfixée par « - » indiquant un tri descendant. Les champs sans préfixe « - » sont triés dans l’ordre ascendant. Indiquez la chaîne « ? » pour trier de façon aléatoire.

  Par exemple, pour trier sur un champ `pub_date` dans l’ordre ascendant, indiquez :

      ordering = ["pub_date"]

  Pour trier par `pub_date` dans l’ordre descendant, indiquez :

      ordering = ["-pub_date"]

  Pour trier par `pub_date` dans l’ordre descendant, puis par `author` dans l’ordre ascendant, indiquez :

      ordering = ["-pub_date", "author"]

  Il est aussi possible d’utiliser des expressions de requête. Pour trier par `author` dans l’ordre croissant et pour que les valeurs nulles apparaissent en dernier, écrivez ceci

      from django.db.models import F

      ordering = [F("author").asc(nulls_last=True)]

Default ordering and GROUP BY

In GROUP BY queries (for example, those using `values()` and `annotate()`), the default ordering is not applied.

Avertissement

Le tri n’est pas une opération anodine. Chaque champ ajouté dans les critères de tri implique un coût au niveau de la base de données. Chaque clé étrangère ajoutée inclut aussi implicitement tous ses champs de tri par défaut.

Si une requête ne possède pas d’ordre de tri, les résultats sont renvoyés de la base de données dans un ordre non défini. Un ordre particulier ne peut être garanti que si l’ordre se base sur un ou des champs qui identifient chaque objet du résultat de manière unique. Par exemple, si un champ `nom` n’est pas unique, le tri par ce champ ne garantit pas que les objets de même nom apparaissent toujours dans le même ordre.

### `permissions`

Options.permissions

  Permissions supplémentaires à intégrer dans la table des permissions lors de la création de cet objet. Les permissions d’ajout, de modification, de suppression et d’affichage sont automatiquement créées pour tous les modèles. Cet exemple ajoute une permission supplémentaire, `can_deliver_pizzas`:

      permissions = [("can_deliver_pizzas", "Can deliver pizzas")]

  Il s’agit d’une liste ou d’un tuple de tuples binaires dans le format `(code_permission, nom_verbeux_permission)`.

### `default_permissions`

Options.default_permissions

  Contient `('add', 'change', 'delete', 'view')` par défaut. Vous pouvez ajuster cette liste, par exemple en définissant une liste vide si votre application n’a besoin d’aucune permission par défaut. Les permissions doivent être définies pour le modèle avant que celui-ci ne soit créé par `migrate` afin d’éviter la création de permissions non utilisées.

### `proxy`

Options.proxy

  Si `proxy = True`, un modèle qui hérite d’un autre modèle sera considéré comme un modèle mandataire.

### `required_db_features`

Options.required_db_features

  Liste de fonctionnalités de base de données que la connexion en cours devrait avoir pour que le modèle soit considéré pendant la phase de migration. Par exemple, si cette liste contient `['gis_enabled']`, le modèle ne sera synchronisé qu’avec les bases de données possédant des fonctionnalités SIG. Ceci est également utile pour omettre certains modèles lors de tests avec plusieurs moteurs de base de données différents. Évitez les relations avec ces modèles qui sont créés conditionnellement car l’ORM ne sait pas comment traiter ces cas.

### `required_db_vendor`

Options.required_db_vendor

  Nom d’un fournisseur de base de données pour lequel ce modèle est spécifique. Les noms des fournisseurs intégrés actuels sont : `sqlite`, `postgresql`, `mysql` et `oracle`. Si cet attribut n’est pas vide et que le fournisseur de la connexion actuelle ne correspond pas, le modèle n’est pas synchronisé.

### `select_on_save`

Options.select_on_save

  Determines if Django will use the pre-1.6 `django.db.models.Model.save()` algorithm. The old algorithm uses `SELECT` to determine if there is an existing row to be updated. The new algorithm tries an `UPDATE` directly. In some rare cases the `UPDATE` of an existing row isn’t visible to Django. An example is the PostgreSQL `ON UPDATE` trigger which returns `NULL`. In such cases the new algorithm will end up doing an `INSERT` even when a row exists in the database.

  Il n’y a habituellement pas besoin de définir cet attribut. La valeur par défaut est `False`.

  See `django.db.models.Model.save()` for more about the old and new saving algorithm.

### `indexes`

Options.indexes

  Une liste des index que vous souhaitez définir pour le modèle :

      from django.db import models

      class Customer(models.Model):
          first_name = models.CharField(max_length=100)
          last_name = models.CharField(max_length=100)

          class Meta:
              indexes = [
                  models.Index(fields=["last_name", "first_name"]),
                  models.Index(fields=["first_name"], name="first_name_idx"),
              ]

### `unique_together`

Options.unique_together

  Utilisez plutôt `UniqueConstraint` avec l’option `constraints`.

  `UniqueConstraint` offre plus de fonctionnalités que `unique_together`. `unique_together` pourra être rendue obsolète dans le futur.

  Noms de champs qui forment ensemble des index uniques :

      unique_together = [["driver", "restaurant"]]

  Il s’agit d’une liste de listes dont les valeurs combinées doivent être uniques. Utilisé dans l’administration de Django et appliqué au niveau base de données (c’est-à-dire que les commandes `UNIQUE` appropriées sont inclues dans les commandes `CREATE TABLE`).

  Par commodité, `unique_together` peut être formé d’une seule liste lorsqu’un seul groupe de champs est défini :

      unique_together = ["driver", "restaurant"]

  Il n’est pas possible d’inclure un champ `ManyToManyField` dans `unique_together` (il n’est même pas évident de savoir ce que ça signifierait). Si vous avez besoin de valider de l’unicité au niveau d’un champ `ManyToManyField`, essayez d’utiliser un signal ou un modèle `through` explicite.

  L’exception `ValidationError` générée durant la validation du modèle lorsque la contrainte est violée possède le code d’erreur `unique_together`.

### `constraints`

Options.constraints

  Une liste des contraintes que vous souhaitez définir pour le modèle :

      from django.db import models

      class Customer(models.Model):
          age = models.IntegerField()

          class Meta:
              constraints = [
                  models.CheckConstraint(condition=models.Q(age__gte=18), name="age_gte_18"),
              ]

### `verbose_name`

Options.verbose_name

  Un nom verbeux pour l’objet, au singulier :

      verbose_name = "pizza"

  Si cette option est absente, Django manipule le nom de la classe : `CamelCase` devient `camel case`.

### `verbose_name_plural`

Options.verbose_name_plural

  Le nom verbeux pluriel pour l’objet :

      verbose_name_plural = "stories"

  Si cette option est absente, Django utilise `verbose_name` et y ajoute un « s ».

## Attributs `Meta` en lecture seule

### `label`

Options.label

  Représentation de l’objet, renvoie `app_label.object_name`, par ex. `'polls.Question'`.

### `label_lower`

Options.label_lower

  Représentation du modèle, renvoie `app_label.model_name`, par ex. `'polls.question'`.