Django的Meta类如何工作?

mik*_*725 165 python django metaclass

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

class FooModel(models.Model):
    ...
    class Meta:
        ...
Run Code Online (Sandbox Code Playgroud)

我在Python的文档中找到的唯一一件事是:

class FooMetaClass(type):
    ...

class FooClass:
    __metaclass__ = FooMetaClass
Run Code Online (Sandbox Code Playgroud)

但是,我不认为这是一回事.

Tad*_*eck 204

您在问两个不同的问题:

  1. MetaDjango模型中的内部类:

    这只是一个类容器,其中包含一些附加到模型的选项(元数据).它定义了诸如可用权限,关联数据库表名,模型是否抽象,名称的单数和复数等内容.

    简短说明如下:Django docs:Models:Meta选项

    可用元选项列表如下:Django docs:Model Meta选项

  2. Python中的元类:

    最好的描述如下:Python中的元类什么?

  • @nnyby:有两件事创造了这两个概念之间的关系:许多用户的名字和混淆(正如OP在原始问题中所说的那样).我相信解决这种常见的混淆是这个topi的重要优势.你不同意吗? (7认同)
  • 这两件事情有关系吗?即,Django的`Meta`内部类是否阻止您使用Python的内置元类功能? (3认同)

Pau*_*ipp 47

扩展Tadeck的Django上面的答案,在Django中使用'class Meta:'也只是普通的Python.

内部类是类实例之间共享数据的方便命名空间(因此,元数据名称为'元数据',但您可以将其称为任何您喜欢的名称).虽然在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
Run Code Online (Sandbox Code Playgroud)

您也可以直接在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>}
Run Code Online (Sandbox Code Playgroud)

但是,在Django中,您更有可能想要在创建模型时探索由模型创建_metaOptions对象属性metaclass.在这里你可以找到所有Django类的'meta'信息.在Django中,Meta仅用于将信息传递到创建_meta Options对象的过程中.

  • 您需要下划线,例如`MyUser.objects.get(pk=1)._meta` (2认同)
  • "类实例之间共享数据的方便命名空间"这一行为我做了. (2认同)

Amb*_*ber 21

Django的Model类专门处理一个名为Metawhich 的属性.这不是一般的Python事情.

Python元类是完全不同的.

  • 我认为你的答案不够清楚 - 你能详细说明`Meta`课是如何运作的吗?我相信OP专门询问了这一点. (12认同)

jhr*_*hrr 5

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

Django模型类对象(即代表类定义本身的对象;是的,类也是对象)的构造实际上是由称为的元类控制的ModelBase,您可以在此处看到该代码:

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

要做的事情之一ModelBase就是_meta在每个Django模型上创建属性,该模型包含验证机制,字段详细信息,保存逻辑等。并且,在此操作期间,将Meta在该过程中读取和使用模型的内部类中指定的内容。

因此,虽然是的,Meta但从某种意义上说,元类是不同的“事物”,但在Django模型构建的机制内,它们是密切相关的;了解它们如何协同工作将一次加深您对这两者的了解。

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

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

如果您想更好地了解对象的总体工作原理,这也可能会有所帮助。

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


小智 5

内部元类文档:

\n

\n模型元数据的此文档django是 \xe2\x80\x9can 任何 \xe2\x80\x99s 不是字段\xe2\x80\x9d 的内容,例如排序选项(ordering), database table name (db_table), or human-readable singular and plural names (verbose_name and verbose_name_plural)。不需要任何内容​​,并且将类 Meta 添加到模型中是完全可选的。\n https://docs.djangoproject.com/en/dev/topics/db/models/#meta-options

\n