---
title: "L’API _meta des modèles"
version: 2.0
locale: fr
source: https://docs.djangoproject.com/fr/2.0/ref/models/meta/
canonical: https://djangodocs.dev/fr/2.0/ref/models/meta/
---
# L’API `_meta` des modèles

#### `class Options`

L’API `_meta` des modèles est au cœur de l’ORM de Django. Elle permet à d’autres parties du système telles que les recherches, les requêtes, les formulaires et le site d’administration de comprendre les capacités de chaque modèle. L’API est accessible au travers de l’attribut `_meta` de chaque classe de modèle, qui est une instance d’objet `django.db.models.options.Options`.

Les méthodes qu’elle fournit peuvent être utilisées pour :

- Récupérer toutes les instances de champ d’un modèle
- Récupérer une instance de champ unique d’un modèle par son nom

## API d’accès aux champs

### Récupération d’une instance de champ unique d’un modèle par son nom

#### `Options.get_field(field_name)`

Renvoie une instance de champ correspondant au nom indiqué.

`field_name` peut être le nom d’un champ du modèle, d’un champ d’un modèle abstrait ou hérité, ou d’un champ défini sur un autre modèle pointant vers ce modèle. Dans ce dernier cas, `field_name` est en fait le nom `related_name` défini par l’utilisateur ou généré automatiquement par Django lui-même.

Les [`champs cachés`](/fr/2.0/ref/models/fields/#django.db.models.Field.hidden) ne peuvent pas être récupérés par leur nom.

Si aucun champ du nom indiqué n’a été trouvé, une exception [`FieldDoesNotExist`](/fr/2.0/ref/exceptions/#django.core.exceptions.FieldDoesNotExist) est générée.

```python
>>> from django.contrib.auth.models import User

# A field on the model
>>> User._meta.get_field('username')
<django.db.models.fields.CharField: username>

# A field from another model that has a relation with the current model
>>> User._meta.get_field('logentry')
<ManyToOneRel: admin.logentry>

# A non existent field
>>> User._meta.get_field('does_not_exist')
Traceback (most recent call last):
    ...
FieldDoesNotExist: User has no field named 'does_not_exist'
```

### Récupération de toutes les instances de champ d’un modèle

#### `Options.get_fields(include_parents=True, include_hidden=False)`

Renvoie un tuple de champs associés à un modèle. `get_fields()` accepte deux paramètres pouvant être utilisés pour contrôler quels champs sont renvoyés :

**`include_parents`**

  `True` par défaut. Inclut récursivement les champs définis dans les classes parentes. Lorsque ce paramètre est défini à `False`, `get_fields()` ne renvoie que les champs déclarés directement sur le modèle concerné. Les champs de modèles qui héritent directement de modèles abstraits ou de classes mandataires sont considérés comme locaux, et non pas définis sur le parent.

**`include_hidden`**

  `False` par défaut. Lorsque ce paramètre est défini à `True`, `get_fields()` inclut les champs utilisés pour fournir des fonctionnalités d’autres champs. Cela comprend également les champs possédant un nom `related_name` (tels que [`ManyToManyField`](/fr/2.0/ref/models/fields/#django.db.models.ManyToManyField) et [`ForeignKey`](/fr/2.0/ref/models/fields/#django.db.models.ForeignKey)) qui commence par un « + ».

```python
>>> from django.contrib.auth.models import User
>>> User._meta.get_fields()
(<ManyToOneRel: admin.logentry>,
 <django.db.models.fields.AutoField: id>,
 <django.db.models.fields.CharField: password>,
 <django.db.models.fields.DateTimeField: last_login>,
 <django.db.models.fields.BooleanField: is_superuser>,
 <django.db.models.fields.CharField: username>,
 <django.db.models.fields.CharField: first_name>,
 <django.db.models.fields.CharField: last_name>,
 <django.db.models.fields.EmailField: email>,
 <django.db.models.fields.BooleanField: is_staff>,
 <django.db.models.fields.BooleanField: is_active>,
 <django.db.models.fields.DateTimeField: date_joined>,
 <django.db.models.fields.related.ManyToManyField: groups>,
 <django.db.models.fields.related.ManyToManyField: user_permissions>)

# Also include hidden fields.
>>> User._meta.get_fields(include_hidden=True)
(<ManyToOneRel: auth.user_groups>,
 <ManyToOneRel: auth.user_user_permissions>,
 <ManyToOneRel: admin.logentry>,
 <django.db.models.fields.AutoField: id>,
 <django.db.models.fields.CharField: password>,
 <django.db.models.fields.DateTimeField: last_login>,
 <django.db.models.fields.BooleanField: is_superuser>,
 <django.db.models.fields.CharField: username>,
 <django.db.models.fields.CharField: first_name>,
 <django.db.models.fields.CharField: last_name>,
 <django.db.models.fields.EmailField: email>,
 <django.db.models.fields.BooleanField: is_staff>,
 <django.db.models.fields.BooleanField: is_active>,
 <django.db.models.fields.DateTimeField: date_joined>,
 <django.db.models.fields.related.ManyToManyField: groups>,
 <django.db.models.fields.related.ManyToManyField: user_permissions>)
```

## Migration à partir de l’ancienne API

Dans le cadre de la formalisation de l’API `Model._meta` (de la classe [`django.db.models.options.Options`](#django.db.models.options.Options)), un certain nombre de méthodes et de propriétés ont été rendues obsolètes et seront supprimées dans Django 1.10.

Ces anciennes API peuvent être reproduites, soit en :

- invoquant [`Options.get_field()`](#django.db.models.options.Options.get_field), ou;
- en invoquant [`Options.get_fields()`](#django.db.models.options.Options.get_fields) pour récupérer une liste de tous les champs, puis en filtrant cette liste à l’aide des [attributs de champ](/fr/2.0/ref/models/fields/#model-field-attributes) qui décrivent (ou récupèrent, dans le cas des variantes `_with_model`) les propriétés des champs souhaités.

Même s’il est possible de créer des remplacements strictement équivalents des anciennes méthodes, ce n’est pas forcément la meilleure approche. Prendre le temps de recréer les énumérations de champs afin de faire meilleur usage de la nouvelle API, en incluant potentiellement des champs qui étaient précédemment exclus, aboutira certainement à un code plus propre.

En supposant qu’un modèle est nommé `MyModel`, il est possible de procéder aux substitutions suivantes pour convertir du code à la nouvelle API :

- `MyModel._meta.get_field(name)` devient :

  ```
  f = MyModel._meta.get_field(name)
  ```

  puis vérifier si :

  - `f.auto_created == False`, parce que la nouvelle API `get_field()` va renvoyer les relations « inverses », et :
  - `f.is_relation and f.related_model is None`, parce que la nouvelle API `get_field()` va renvoyer les relations [`GenericForeignKey`](/fr/2.0/ref/contrib/contenttypes/#django.contrib.contenttypes.fields.GenericForeignKey).
- `MyModel._meta.get_field_by_name(name)` renvoie un tuple de ces quatre valeurs avec les remplacements suivants :

  - `field` peut être trouvé par `MyModel._meta.get_field(name)`
  - `model` peut être trouvé par l’attribut [`model`](/fr/2.0/ref/models/fields/#django.db.models.Field.model) du champ.
  - `direct` peut être trouvé par : `not field.auto_created or field.concrete`

    Le contrôle [`auto_created`](/fr/2.0/ref/models/fields/#django.db.models.Field.auto_created) exclut toute relation « vers l’avant » ou « inverse » créée par Django, mais cela comprend également les champs `AutoField` et `OneToOneField` sur les modèles mandataires. Nous évitons d’exclure ces champs à l’aide de l’attribut [`concrete`](/fr/2.0/ref/models/fields/#django.db.models.Field.concrete).
  - `m2m` peut être trouvé au moyen de l’attribut [`many_to_many`](/fr/2.0/ref/models/fields/#django.db.models.Field.many_to_many) du champ.
- `MyModel._meta.get_fields_with_model()` devient :

  ```
  [
      (f, f.model if f.model != MyModel else None)
      for f in MyModel._meta.get_fields()
      if not f.is_relation
          or f.one_to_one
          or (f.many_to_one and f.related_model)
  ]
  ```
- `MyModel._meta.get_concrete_fields_with_model()` devient :

  ```
  [
      (f, f.model if f.model != MyModel else None)
      for f in MyModel._meta.get_fields()
      if f.concrete and (
          not f.is_relation
          or f.one_to_one
          or (f.many_to_one and f.related_model)
      )
  ]
  ```
- `MyModel._meta.get_m2m_with_model()` devient :

  ```
  [
      (f, f.model if f.model != MyModel else None)
      for f in MyModel._meta.get_fields()
      if f.many_to_many and not f.auto_created
  ]
  ```
- `MyModel._meta.get_all_related_objects()` devient :

  ```
  [
      f for f in MyModel._meta.get_fields()
      if (f.one_to_many or f.one_to_one)
      and f.auto_created and not f.concrete
  ]
  ```
- `MyModel._meta.get_all_related_objects_with_model()` devient :

  ```
  [
      (f, f.model if f.model != MyModel else None)
      for f in MyModel._meta.get_fields()
      if (f.one_to_many or f.one_to_one)
      and f.auto_created and not f.concrete
  ]
  ```
- `MyModel._meta.get_all_related_many_to_many_objects()` devient :

  ```
  [
      f for f in MyModel._meta.get_fields(include_hidden=True)
      if f.many_to_many and f.auto_created
  ]
  ```
- `MyModel._meta.get_all_related_m2m_objects_with_model()` devient :

  ```
  [
      (f, f.model if f.model != MyModel else None)
      for f in MyModel._meta.get_fields(include_hidden=True)
      if f.many_to_many and f.auto_created
  ]
  ```
- `MyModel._meta.get_all_field_names()` devient :

  ```
  from itertools import chain
  list(set(chain.from_iterable(
      (field.name, field.attname) if hasattr(field, 'attname') else (field.name,)
      for field in MyModel._meta.get_fields()
      # For complete backwards compatibility, you may want to exclude
      # GenericForeignKey from the results.
      if not (field.many_to_one and field.related_model is None)
  )))
  ```

  Cela fournit un remplacement 100 % rétrocompatible, garantissant que les noms de champ et les noms d’attribut `ForeignKey` sont inclus, mais que les champs associés à `GenericForeignKey` ne le sont pas. Une version simplifiée pourrait être :

  ```
  [f.name for f in MyModel._meta.get_fields()]
  ```

  Même si cette variante n’est pas rétrocompatible à 100 %, elle peut suffire dans bien des situations.
