Django模型如何工作?

时间:2012-08-17 12:54:49

标签: python django django-models

所以我可以像这样创建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__.titlelink

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

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

1,Django会在幕后创建属性“title”吗?

2,类变量“title”发生了什么变化?

2 个答案:

答案 0 :(得分:17)

我认为很难击败Django文档对say on this的看法。

  

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

基本上metaclass定义了如何创建类本身。在创建过程中,可以将其他属性/方法/任何内容绑定到该类。这个stackoverflow answer给出的例子,大写了类的所有属性

# 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的模型元类可以消化你应用于类的属性,并为验证/等添加各种有用的属性,包括偶数方法和什么不是。

答案 1 :(得分:2)

python非常强大,允许开发人员使用intrespection。

django使用了很多元类。似乎models.Model也使用它。看到了 django的\分贝\模型\ base.py

class Model(object):
    __metaclass__ = ModelBase

我认为元类只接受类属性这样的类,对于这些模型子类的所有新实例,创建适当的变量。

1)是的,django自动创建属性“title”的实例变量 2)以同样的方式,元类将字段移动到元类......