django的嵌套元类是如何工作的?

我使用的是Django,它允许人们通过使用class Meta向类添加额外的参数。

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

我在Python的文档中唯一找到的东西是:

class FooMetaClass(type):
...


class FooClass:
__metaclass__ = FooMetaClass

然而,我不认为这是一回事。

148088 次浏览

Django的Model类专门处理名为Meta的属性,这是一个类。这不是一般的Python。

Python元类是完全不同的。

你在问两个不同的问题:

  1. < p > Django模型中的Meta内部类:

    这只是一个类容器,带有附加到模型的一些选项(元数据)。它定义了可用的权限、关联的数据库表名、模型是否是抽象的、名称的单数和复数版本等。

    简短的解释在这里:Django文档:模型:元选项

    可用的元选项列表在这里:Django文档:Meta选项模型

    对于最新版本的Django: Django文档:Meta选项模型

  2. < p > Python中的元类:

    最好的描述在这里:Python中的元类是什么?

根据上面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中,你更可能想要探索_meta属性,它是模型创建时由模型metaclass创建的Options对象。在这里你可以找到所有Django类的“元”信息。在Django中,Meta只是用来将信息传递到创建_meta Options对象的过程中。

声称Django模型的Meta和元类“完全不同”的答案;都是误导性的答案。

Django模型类对象的构造,也就是说代表类定义本身的对象(是的,类也是对象),确实是由一个名为ModelBase的元类控制的,你可以看这里的代码

ModelBase所做的其中一件事就是在每个Django模型上创建_meta属性,其中包含验证机制、字段细节、保存逻辑等。在此操作期间,在模型的内部Meta类中指定的内容将在该进程中读取和使用。

所以,虽然在某种意义上Meta和元类是不同的“东西”,但在Django模型构建的机制中,它们是密切相关的;了解它们是如何一起工作的将加深你对两者的洞察力。

这可能是更好地理解Django模型如何使用元类的有用信息来源。

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

如果你想更好地理解对象一般是如何工作的,这可能也会有所帮助。

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

内部元类文档:

django的文档 模型元数据是“任何不是字段的东西”,比如排序选项(ordering), database table name (db_table), or human-readable singular and plural names (verbose_name and verbose_name_plural)。没有一个是必需的,将类Meta添加到模型中是完全可选的。 https://docs.djangoproject.com/en/dev/topics/db/models/#meta-options < / p >

在Django中,它作为一个配置类,并将配置数据保存在一个地方!!

是在你的代码逻辑中,你的< >强model.fields < / >强 满足和你的< >强form.widgets < / >强。 因此,在Class Meta()下,您可以在您的模型字段和您想要在表单中拥有的不同小部件之间创建链接