web-dev-qa-db-fra.com

Comment fonctionne la classe Meta de Django?

J'utilise Django qui permet aux utilisateurs d'ajouter des paramètres supplémentaires à une classe en utilisant class Meta.

class FooModel(models.Model):
    ...
    class Meta:
        ...

La seule chose que j'ai trouvée dans la documentation de Python était:

class FooMetaClass(type):
    ...

class FooClass:
    __metaclass__ = FooMetaClass

Cependant, je ne pense pas que ce soit la même chose.

158
miki725

Vous posez une question sur deux choses différentes:

  1. Meta classe interne dans Django modèles :

    Ceci est juste un conteneur de classe avec des options (métadonnées) attachées au modèle. Il définit des éléments tels que les autorisations disponibles, le nom de la table de base de données associée, si le modèle est abstrait ou non, les versions du nom au singulier et au pluriel, etc.

    Une brève explication est ici: Django docs: Models: Meta options

    La liste des options de méta disponibles est la suivante: Django docs: Options de modèle de méta

  2. Métaclasse en Python :

    La meilleure description est la suivante: Qu'est-ce qu'une métaclasse en Python?

198
Tadeck

En prolongeant la réponse de Django de Tadeck ci-dessus, l'utilisation de 'classe Meta:' dans Django est tout simplement normale Python.

La classe interne est un espace de noms pratique pour les données partagées entre les instances de classe (d'où le nom Meta pour 'métadonnées' mais vous pouvez l'appeler comme bon vous semble). Bien que, dans Django, il s’agisse généralement d’une configuration en lecture seule, rien ne vous empêche de le modifier:

In [1]: class Foo(object):
   ...:     class Meta:
   ...:         metaVal = 1
   ...:         
In [2]: f1 = Foo()
In [3]: f2 = Foo()
In [4]: f1.Meta.metaVal
Out[4]: 1
In [5]: f2.Meta.metaVal = 2
In [6]: f1.Meta.metaVal
Out[6]: 2
In [7]: Foo.Meta.metaVal
Out[7]: 2

Vous pouvez l'explorer dans Django directement aussi, par exemple:

In [1]: from Django.contrib.auth.models import User
In [2]: User.Meta
Out[2]: Django.contrib.auth.models.Meta
In [3]: User.Meta.__dict__
Out[3]: 
{'__doc__': None,
 '__module__': 'Django.contrib.auth.models',
 'abstract': False,
 'verbose_name': <Django.utils.functional.__proxy__ at 0x26a6610>,
 'verbose_name_plural': <Django.utils.functional.__proxy__ at 0x26a6650>}

Cependant, dans Django, vous voudrez probablement explorer l'attribut _meta qui est un objet Options créé par le modèle metaclass lors de la création d'un modèle. C'est là que vous trouverez toutes les informations 'méta' de la classe Django. Dans Django, Meta est simplement utilisé pour passer des informations au processus de création de l'objet _metaOptions.

45
Paul Whipp

La classe Model de Django gère spécifiquement le fait d'avoir un attribut nommé Meta qui est une classe. Ce n'est pas une chose générale Python.

Les métaclasses Python sont complètement différentes.

20
Amber

Les réponses qui prétendent Django du modèle Meta du modèle et des métaclasses sont "complètement différentes" sont des réponses trompeuses.

La construction de Django modèle objets de classe (c'est-à-dire l'objet qui représente la définition de classe elle-même; oui, les classes sont également des objets) sont en effet contrôlés par une métaclasse appelée ModelBase, vous pouvez voir ce code ici:

https://github.com/Django/django/blob/master/Django/db/models/base.py#L61

Et l'une des choses que fait ModelBase est de créer l'attribut _meta sur chaque modèle Django qui contient la machinerie de validation, les détails de la parcelle, la sauvegarde de la machinerie, etc. Et, pendant cette opération, tout ce qui est spécifié dans la classe inner Meta du modèle est lu et utilisé dans ce processus.

Donc, bien que oui, dans un sens, Meta et que les métaclasses soient des "choses" différentes, elles sont intimement liées dans la mécanique de la construction du modèle Django; Si vous comprenez comment ils travaillent ensemble, vous approfondirez votre compréhension à la fois.

Cela pourrait être une source d’information utile pour mieux comprendre comment les modèles Django utilisent des métaclasses.

https://code.djangoproject.com/wiki/DevModelCreation

Et cela pourrait aussi vous aider si vous souhaitez mieux comprendre le fonctionnement des objets en général.

https://docs.python.org/3/reference/datamodel.html

4
jhrr

Document de classe Meta interne Ce document de Django Les métadonnées de modèle sont “tout ce qui n'est pas un champ”, telles que les options de classement (ordering), le nom de la table de la base de données (db_table) ou les noms singulier et pluriel lisibles par l'homme (nom_profil et nom_babulaire_plural). Aucune n'est requise, et l'ajout de la classe Meta à un modèle est totalement facultatif. https://docs.djangoproject.com/en/dev/topics/db/models/#meta-options

0
Sujeet