模型
模型是數據獨有的限定性源。它包括所存儲數據的必要的字段及數據行爲。總體上說,每個模型映射到唯一的一張數據庫表上。
基本要點:
每個模型都是一個Python類,這個類是django.db.models.Model的子類。
模型類的每個屬性代表了一個數據庫字段。
通過以上所提到的兩點,Django爲我們提供了一整套自動生成的數據庫存取API;查看執行查詢(Making queries)。
例子:
這個例子定義了一個Person模型,它有first_name和last_name兩個字段:
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
first_name和last_name是模型的兩個字段。每個字段被指定爲一個類屬性,每個屬性映射爲一個數據庫表的列。
上面的Person模型將會生成如下所示的數據庫表:
CREATE TABLE myapp_person (
"id" serial NOT NULL PRIMARY KEY,
"first_name" varchar(30) NOT NULL,
"last_name" varchar(30) NOT NULL
);
需要注意的一些知識點如下:
數據表的表名myapp_person是自動從模型元數據中衍生出來的,當然也可以自定義。查看錶名以瞭解更多細節... …
字段id是自動添加的,當然這個特性也可以自定義。查看自動主鍵字段。
這個例子中的SQL命令CREATE TABLE採用的是PostgreSQL語法,需要指出的是,Django根據settings文件中指定的數據庫後臺來確定採用哪種一致的SQL語法。
使用模型
一旦完成了模型的定義,下一步就需要告訴Django要使用這些模型。要做到這一點,需要編輯settings文件,更改INSTALLED_APPS項,將包括models.py的模塊名添加進去。
例如,假設mysite.myapp.models模塊包含應用程序的模型(應用程序的包結構由腳本命令manage.py startapp生成),INSTALLED_APPS看起來就像這樣(部分地):
INSTALLED_APPS = (
#...
'mysite.myapp',
#...
)
在INSTALLED_APPS中添加新的應用程序之後,一定要確保運行manage.py syncdb命令。
字段
模型的最重要的部分,也即非可或缺的部分當屬數據庫中要定義的字段的列表。字段由類的屬性指定。
例如:
class Musician(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
instrument = models.CharField(max_length=100)
class Album(models.Model):
artist = models.ForeignKey(Musician)
name = models.CharField(max_length=100)
release_date = models.DateField()
num_stars = models.IntegerField()
字段類型
模型中的每一個字段須是相應的字段類(Field class)的一個實例。Django的字段類(Field class)決定了:
數據庫中列的類型(例如,INTEGER,VARCHAR)。
在Django的後臺應用程序(admin)界面中要使用什麼部件(例如,<input type=”text”>,<select>)。
在Django的後臺應用程序(admin)以及自動生成的表單中的基本驗證需求。
Django附帶有十幾種內建字段類型;你可以在模型字段參考中查看完整列表。如果內建字段類型無法滿足需要,你可以很輕鬆地構建自己的字段類型;可以查看自定義模型字段一節。
字段選項
每一個字段都有一些相應的字段參數(相應文檔可以查看模型字段參考)。例如,CharField(及其子類)使用max_length參數指定對應的用於保存數據的數據庫字段VARCHAR的字段長度。
一些公共參數適用於所有的字段類型。它們都是可選的。它們的完整解釋可以參考手冊中找到,以下是一些最常使用的參數的大致介紹:
null
如果null的值爲True,Django會以NULL在數據庫保存空值。它的默認值爲False。
blank
如果blank的值爲True,相應數據庫字段將允許值爲空。它的默認值爲False。
注意blank和null是有區別的。Null是純粹的數據庫相關的選項,而blank是驗證相關的選項。如果一個字段設置了選項blank=True,在Django的admin應用程序中將允許該字段輸入空值。如果一個字段設置了選項blank=False,該字段將爲必填字段。
Choices
一個二元的可迭代值(列表或元組)可以作爲一個字段的可選擇項。如果設置了該選項,Django的admin應用程序將會以選擇框取代標準的文本輸入框,並且輸入僅限於所定的選項。
一個choices列表看起來就像這樣:
YEAR_IN_SCHOOL_CHOICES = (
(u'FR', u'Freshman'),
(u'SO', u'Sophomore'),
(u'JR', u'Junior'),
(u'SR', u'Senior'),
(u'GR', u'Graduate'),
)
每一個元組中的第一個元素的值表示要在數據庫中存儲的值。第二個元素的值爲在admin應用程序界面上顯示的內容,或顯示在模型選擇字段(ModelChoiceField)中。對於一個模型對象的實例來說,choices字段的第二個元素的值可以通過get_FOO_display方法來獲取。例如:
from django.db import models
class Person(models.Model):
GENDER_CHOICES = (
(u'M', u'Male'),
(u'F', u'Female'),
)
name = models.CharField(max_length=60)
gender = models.CharField(max_length=2, choices=GENDER_CHOICES)
>>> p = Person(name="Fred Flinstone", gender="M")
>>> p.save()
>>> p.gender
u'M'
>>> p.get_gender_display()
u'Male'
default
表示字段的默認值。可以是值,也可以是可調用對象。如果默認值是可調用對象,那麼每創建一個新實例,它都會被調用一次。
help_text
顯示在admin表單下的相應字段的額外的“幫助”文本。即使對象沒有使用admin表單,它對於文檔清晰也是有幫助的。
primary_key
如果primary_key的值爲True,該字段將是模型的主鍵。
如果在模型中你沒有爲任何一個字段指定primary_key=True,Django將自動添加一個IntegerField類型的字段用於主鍵,所以爲字段設置primary_key=True選項不是必需的,除非你想覆蓋掉默認行爲。更多細節,請查看自動主鍵字段一節(Automatic primary key fields)。
unique
如果unique的值爲True,這個字段的值在數據庫表中須是唯一的。
再次重申,這些僅僅是常用字段選項的簡單介紹。完整的描述可在查看通用模型字段選項參考(common model field option reference)。
自動主鍵字段(Automatic primary key fields)
默認地,Django爲每一個模型提供了以下字段:
id = models.AutoField(primary_key=True)
這是一個值自動增加的主鍵。
如果你想指定一個自定義主鍵,僅需在相應字段中指定primary_key=True即可。如果Django看到你明確地指定了Field.primary_key,它將不再自動地添加id列。
每一個模型都需要且僅需要一個字段有primary_key=True這個選項。
詳細字段名(Verbose field names)
每一個字段類型,除ForeignKey,ManyToManyField和OneToOneField之外,帶有一個可選的處於最前面的位置參數--- ---詳細名稱。如果沒有提供詳細名稱參數,Django將會採用字段的屬性名,並且必要時轉換下劃線爲空格。
下例中,詳細名爲“Person’s first name”:
first_name = models.CharField("Person's first name", max_length=30)
下例中,詳細名爲“first name”:
first_name = models.CharField(max_length=30)
ForeignKey,ManyToManyField和OneToOneField字段的第一個參考必須爲一個模型類,所以它必須使用關鍵字參數:
poll = models.ForeignKey(Poll, verbose_name="the related poll")
sites = models.ManyToManyField(Site, verbose_name="list of sites")
place = models.OneToOneField(Place, verbose_name="related place")
按照慣例,詳細字段名的第一個字母不必大寫。Django將會在需要時自動轉換大小寫