2012-08-17 51 views
18

所以我可以創造的Django模型是這樣的: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

但是在Django當我創造一些實例我突然有一個標題屬性,我可以獲取/設置文本。而不能訪問它thing.__class__.title很清楚,當做thing.title我沒有訪問類變量「標題」,但一些生成的屬性/財產,或?

我知道字段以thing._meta.fields結尾,但是如何? 怎麼回事?

1,Django在幕後製作屬性「標題」嗎?

2,類變量「title」發生了什麼?

回答

16

我認爲它很難打敗Django文檔中的say on this

模型類(參見base.py)具有元類屬性,它定義模型庫(也在base.py)作爲類使用用於創建新的類。所以ModelBase。 新的被調用來創建這個新的示例類。認識到我們在這裏創建類對象是非常重要的,而不是它的一個實例。換句話說,Python正在創建最終將綁定到我們當前名稱空間中的示例名稱的東西。

基本上一個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

感謝鏈接到文件上的代碼。 djangoproject.com!我只是在docs.djangoproject.com尋找解釋 – Michal 2012-08-17 13:34:18

+0

因此metacclass可以添加屬性,方法等,但是它也可以刪除屬性/方法等,因爲CharField類型的類變量標題被清除了嗎?或者不是嗎? – Michal 2012-08-17 13:37:30

+0

@Michal當然,記住所有的python屬性都存儲在'__dict__'中。通過操作'__dict__'你可以做任何事情。 – 2012-08-17 13:38:12

2

python是非常強大的,並允許開發人員使用intrespection。

django使用了很多元類。它似乎是模型。模型也使用它。看到 Django的\ DB \型號\ base.py

class Model(object): 
    __metaclass__ = ModelBase 

我認爲元類只取類屬性,這樣的領域,併爲這些型號的子類的所有新實例,創建apropriate變量。

1)是的,Django的創造財產的實例變量「標題」 automaticaly 2)以同樣的方式,元類移動領域成元類...