21

所以我可以像这样创建 Django 模型:

from django.db import models

class Something(models.Model):
    title = models.TextField(max_length=200)

我可以像这样使用它:

thing = Something()
#set title
thing.title = "First thing"
#get title
thing.title

一切正常,但我想了解它是如何工作的。

title = models.TextField(max_length=200)

在上面的非Django Python代码中定义了models.TextField类型的类变量标题,我也可以像这样访问它thing.__class__.title:(链接

但是在 Django 中,当我创建Something 的实例时,我突然有了一个标题属性,我可以在其中获取/设置文本。并且thing.__class__.title在做thing.title时无法使用So clear访问它我不是在访问类变量“title”而是一些生成的属性/属性,或者?

我知道字段最终出现在 thing._meta.fields 但如何?发生了什么以及如何?

1、Django是否在幕后创建属性“title”?

2、类变量“title”怎么了?

4

2 回答 2

17

我认为它很难击败 Django 文档对此的说法

Model 类(参见 base.py)有一个元类属性,它将 ModelBase(也在 base.py 中)定义为用于创建新类的类。所以模型库。调用new来创建这个新的 Example 类。重要的是要意识到我们在这里创建的是类对象,而不是它的实例。换句话说,Python 正在创建最终将绑定到我们当前命名空间中的示例名称的东西。

基本上,元类定义了如何创建类本身。在创建期间,可以将其他属性/方法/任何东西绑定到该类。这个stackoverflow答案给出的例子,大写了一个类的所有属性

# remember that `type` is actually a class like `str` and `int`
# so you can inherit from it
class UpperAttrMetaclass(type): 
    # __new__ is the method called before __init__
    # it's the method that creates the object and returns it
    # while __init__ just initializes the object passed as parameter
    # you rarely use __new__, except when you want to control how the object
    # is created.
    # here the created object is the class, and we want to customize it
    # so we override __new__
    # you can do some stuff in __init__ too if you wish
    # some advanced use involves overriding __call__ as well, but we won't
    # see this
    def __new__(upperattr_metaclass, future_class_name, 
                future_class_parents, future_class_attr):

        attrs = ((name, value) for name, value in future_class_attr.items() if not name.startswith('__'))
        uppercase_attr = dict((name.upper(), value) for name, value in attrs)

        return type(future_class_name, future_class_parents, uppercase_attr)

以类似的方式,Django 的模型元类可以消化您应用于该类的属性,并添加各种有用的属性用于验证/等,包括偶数方法和非类。

于 2012-08-17T13:24:01.943 回答
2

python is extremely powerfull and permit the developer to use intrespection.

django use a lot of metaclass. and it seem that models.Model use it too. see in django\db\models\base.py

class Model(object):
    __metaclass__ = ModelBase

i think the metaclass just take the classes attributes such a the Field and for all new instance for these Model subclass,create the apropriate variable.

1) yes, django create the instance variable of property "title" automaticaly 2) in the same way, the metaclass move the fields into the meta class...

于 2012-08-17T13:49:37.970 回答