2014-07-03 42 views
0

從Django中的文件之前,我知道如果我這樣定義的模型:如何Django的設置對象的方法它被定義

class Person(models.Model): 
    SIZE = (
     ('S','Small') 
     ('M','Medium') 
    ) 
    size = models.CharField(max_length = 1, choices = SIZE) 

然後我對人的方法稱爲get_size_display()

我不知道Django是如何實現這一功能。它如何知道我有一個名爲sizePerson的屬性,並在方法名稱中使用它?這是python中的一個竅門嗎?

+0

參見[什麼是Python中的元類?(http://stackoverflow.com/q/100003) –

回答

0

Django使用Python的元類來實現這一目標。

就像一個普通class是從中創建對象的模板,元類是是從創建類的模板。

在聲明常規class

class A(object): 
    pass 

默認元類(type)就是負責創建A。它通過處理您在A中定義的內容來創建實際上代表A的對象。

在Django中,開發商改變了models.Model元類自己的定製元類。在這樣做時,他們可以控制從models.Model派生的任何類的創建,並且可以執行您所指的「魔術」。

Django使用類似魔術做很多其他的事情呢!


例如,我可以做以下複製你所看到的Django做什麼:

class MetaClass(type): 
    @staticmethod 
    def _create_getter(attr): 
     def _getter(self): 
      return getattr(self, attr) 
     return _getter 

    def __init__(self, name, bases, attrs): 
     super(MetaClass, self).__init__(name, bases, attrs) 

     for attr in attrs: 
      if not attr.startswith('_'): 
       setattr(self, 'get_%s' % attr, MetaClass._create_getter(attr)) 

class Base(object): 
    __metaclass__ = MetaClass 

現在,從Base派生將自動獲取各個它的公共屬性的getter方法的任何類(那些不以_開頭)。

這裏的正在使用:

class A(Base): 
    x = 2 

a = A() 
print a.get_x() 
+0

很好的解釋!然而,stackoverflow說我沒有足夠的聲望投票給你。 –

+0

但是,您應該能夠接受我的答案。 –

相關問題