2009-02-01 90 views
10

首先,我沒有進入網絡編程。我碰到了django並閱讀了一些關於模型的內容。我被下面的代碼(從djangoproject.com)很感興趣:Django模型字段如何工作?


class Person(models.Model): 
    first_name = models.CharField(max_length=50) 
    last_name = models.CharField(max_length=50) 

    def __str__(self): 
     # Note use of django.utils.encoding.smart_str() here because 
     # first_name and last_name will be unicode strings. 
     return smart_str('%s %s' % (self.first_name, self.last_name)) 

通過我的蟒蛇,FIRST_NAME的理解和姓氏是類變量,對不對?在代碼中如何使用它(因爲我猜想設置Person.first_name或Person.last_name會影響所有Person實例)?爲什麼這樣使用?

回答

4

是的,first_name和last_name是類變量。他們定義將在數據庫表中創建的字段。有一個Person表具有first_name和last_name列,所以在這一點上它們在Class級別上是有意義的。

更多關於型號,請參閱: http://docs.djangoproject.com/en/dev/topics/db/models/

當談到訪問代碼的人的情況下,你通常是通過Django的ORM這樣做,在這一點上,他們本質上表現爲實例變量。

更多關於模型實例,請參見: http://docs.djangoproject.com/en/dev/ref/models/instances/?from=olddocs

+0

丹科舍恩安迪! – Geo 2009-02-01 13:00:00

+0

這裏有一些很好的鏈接,但是「在這一點上它們本質上表現爲實例變量」是一點手勢,並非真正準確(或者至少沒有解釋任何東西)。 – 2009-02-01 18:44:16

19

你的問題的實質是「怎麼來的這些類變量(我分配領域對象)突然變得實例變量(我分配數據)在Django的ORM「?答案就是Python metaclasses的魔力。

元類允許您掛接並修改創建Python類(而不是創建該類的實例,創建類本身)的過程。

Django的模型對象(因此也是您的模型,它們是子類)有一個ModelBase metaclass。它會查看模型的所有類屬性,以及它是Field子類的實例,它將移入字段列表中。該列表被分配爲_meta對象的屬性,該屬性是模型的類屬性。因此,您可以始終通過MyModel._meta.fieldsMyModel._meta.get_field('field_name')訪問實際的Field對象。

然後,Model.__init__方法可以使用_meta.fields列表來確定創建模型實例時應初始化哪些實例屬性。

不要害怕跳入Django源代碼;這是一個很好的教育來源!

0

不是一個真正的答案,但對於豐富:

Person.first_name 

將無法​​正常工作

p = Person.objects.get(pk=x) 
p.first_name 

會工作。所以人的對象實例具有名和姓,但靜態上下文Person不具有。

另請注意:Django擁有允許「Person」執行靜態查詢集操作的模型管理器。 (https://docs.djangoproject.com/en/dev/topics/db/managers/#managers)。

因此,例如

peoples = Person.objects.all()