web-dev-qa-db-ja.com

DjangoのMetaクラスはどのように機能しますか?

私はDjangoを使用しています。これにより、class Metaを使用して、クラスに追加のパラメーターを追加できます。

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

Pythonのドキュメントで私が見つけた唯一のものは:

class FooMetaClass(type):
    ...

class FooClass:
    __metaclass__ = FooMetaClass

しかし、これは同じことだとは思いません。

158
miki725

次の2つのことについて質問しています。

  1. Meta Djangoモデルの内部クラス

    これは、モデルに添付されたいくつかのオプション(メタデータ)を持つ単なるクラスコンテナーです。使用可能な権限、関連するデータベーステーブル名、モデルが抽象的かどうか、名前の単数形と複数形などを定義します。

    簡単な説明はこちら: Django docs:Models:Meta options

    利用可能なメタオプションのリストはこちらです: Django docs:Model Meta options

  2. Pythonのメタクラス

    最良の説明はこちらです: Pythonのメタクラスとは?

198
Tadeck

上記のTadeckのDjangoの回答を拡張すると、Djangoでの 'class Meta:'の使用も通常のPythonになります。

内部クラスは、クラスインスタンス間で共有されるデータの便利な名前空間です(したがって、「メタデータ」の名前はMetaですが、任意の名前を付けることができます)。 Djangoでは通常、読み取り専用の構成要素ですが、変更を止めることはできません。

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

Djangoで直接探索することもできます。例:

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>}

ただし、Djangoでは、モデルの作成時にOptionsモデルによって作成されたmetaclassオブジェクトである_meta属性を探索する可能性が高くなります。ここで、Djangoクラスの「メタ」情報をすべて見つけることができます。 Djangoでは、Metaは、_metaOptionsオブジェクトを作成するプロセスに情報を渡すためにのみ使用されます。

45
Paul Whipp

DjangoのModelクラスは、クラスであるMetaという名前の属性を持つことを特に処理します。一般的なPythonのことではありません。

Pythonメタクラスは完全に異なります。

20
Amber

DjangoモデルのMetaおよびメタクラスが「完全に異なる」と主張する回答は、誤解を招く回答です。

Django modelclass objectsの構築(つまり、クラス定義自体を表すオブジェクト。はい、クラスはまた、オブジェクト)は実際にModelBaseというメタクラスによって制御されます。そのコードは次のとおりです。

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

ModelBaseが行うことの1つは、検証機構、フィールドの詳細、保存機構などを含むすべてのDjangoモデルに_meta属性を作成することです。そして、この操作中に、モデルの内部Metaクラスで指定されたものはすべて読み取られ、そのプロセス内で使用されます。

そのため、はい、ある意味ではMetaとメタクラスは異なる「もの」ですが、Djangoモデル構築のメカニズム内では、それらは密接に関連しています。それらがどのように連携するかを理解することで、両方の洞察を一度に深めることができます。

これは、Djangoモデルがメタクラスをどのように使用するかをよりよく理解するための有用な情報源になる可能性があります。

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

また、これは、オブジェクトが一般的にどのように機能するかをよりよく理解したい場合にも役立ちます。

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

4
jhrr

内部メタクラスドキュメントDjangoモデルメタデータのこのドキュメントは、順序付けオプション(順序付け)、データベーステーブル名(db_table)、または人が読める単数形と複数形の名前(verbose_name)などの「フィールドではないすべて」です。およびverbose_name_plural)。どれも必須ではなく、クラスMetaをモデルに追加することは完全にオプションです。 https://docs.djangoproject.com/en/dev/topics/db/models/#meta-options

0
Sujeet