本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫
模型設計
回顧
前三章我們可以算是一腳邁進了Django的大門(也稱入坑),因為程式設計師入坑第一步就是學會Hello World。希望你別驕傲,我們接下來才是真正的旅途——一起領略Django真正的迷人之處。
模型本質
現在,我們來學習模型,Django模型層是Django框架自定義的一套獨特的ORM(Object Relational Mapping,關係映射模型)技術。
模型本質上就是資料庫表的布局,再附加一些元數據。模型包含了你要在資料庫中創建的欄位信息及對數據表的一些操作。
基本操作
想要操作模型,我們先來了解Django模型層的大概。使用Django模型開發的首要任務就是定義模型類及其屬性,每個模型的物理存在方式就是一個Python的類Class,每個模型代表資料庫中的一張表,每個類的實例代表數據表中的一行數據,而類中的每個屬性被映射為數據表中的一列欄位。
可能你還是很懵逼,沒關係,我們從偽代碼中再來看看這些概念。
模型類定義模型定義的基本結構如下:
from django.db import modelsclass ModelName(models.Model):field1 = models.XXField(...) fiels2 = models.XXField(...) ... class Meta: db_table = ... other metas = ...
解析如下:
所有Django模型都是django.db.models.Model類的子類。每個類都會被轉換為資料庫表通過其中的類屬性定義模型欄位,模型欄位必須是某種models.XXField類型,比如CharField,DateTimeField等等,而這些就會被轉換為對應資料庫表中的列通過模型類中的Meta子類定義模型元數據,比如資料庫表名、數據默認排序方式等。我們來詳細看一個樣例:定義了一個 Person, 其擁有 first_name 和 last_name:
from django.db import modelsclass 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);
我們介紹一下class Meta中的那些屬性,Meta類的屬性名由Django預定義,我們無需自己創建,Model 元數據就是 "不是一個欄位的任何數據" -- 比如排序選項,常見的Meta類屬性匯總如下:
abstract: True or False,標識本類是否為抽象基類app_label:定義本類所屬的應用,比如app_labels = 'myapp'db_table:映射的數據表名,比如db_table='db_blogs'default_related_name:定義本模型的反向關係引用名稱,默認與模型名一致。ordering:本模型記錄的默認排序欄位,可以設置多個欄位,默認以升序排列,如果降序需要在欄位前加「負號」。比如,按文章發布時間降序顯示:
class Meta:ordering = ("-publish_date", ) # 按照publish欄位值的倒序顯示
...還有很多其他的選項,我們暫時先不列出,有興趣的可以自行查看Django文檔Model Meta options,先混個眼熟,等項目中具體用到我們再添加。上訴只是簡單列出一些能用到的 Meta 選項。我們需要注意的使:沒有一個選項是必需的,是否添加 class Meta 到你的 model 完全是可選的。
普通欄位類型普通欄位類型是指模型類中除外鍵關係外的數據欄位類型。數據欄位為Django使用模型時提供如下信息。
在資料庫中用什麼類型定義模型欄位,比如INTEGER、VARCHAR等。用什麼樣的HTML標籤顯示模型欄位,比如<input type="radio">等。需要什麼樣的HTML表單數據驗證。所有的數據欄位的屬性必須繼承自抽象類django.db.models.Field,我們可以使用Django預定義的一系列Field子類,也可以自己定義繼承該類的欄位類型。
AutoField:一個自動遞增的整型欄位,添加記錄時它會自動增長。AutoField欄位通常用於數據表的主鍵;如果模型中沒有指定主鍵欄位,則Django會自動添加一個AutoField欄位。BigIntegerField:64位整型欄位CharField:字符串欄位,用於較短的字符串,相對應的HTML標籤是單行輸入框<input type="text">TextField:大容量文本欄位,相對應的HTML標籤是多行編輯框<textarea>更多欄位類型,參見官方Model field reference常用的欄位參數每個欄位類型都有一些特定的HTML標籤和表單驗證參數,比如height_field、path等。
primary_key參數:設置一個模型的主鍵欄位,為True或False
from django.db import modelsclass Person(models.Model):id = models.AutoField(primary_key=True)
null:定義是否允許相對應的資料庫欄位為Null,默認設置為Falseblank:如果為True,則該欄位允許為空白。默認值為False請注意,這個欄位與null有所不同。null與資料庫完全相關,是資料庫的飛空約束;而blank與表單驗證相關。如果欄位包含blank=True,則表單驗證將允許輸入一個空值。
choices:定義欄位的可選值,本欄位的值應該是一個包含二維元素的元組,第一個元素是實際存儲的值,第二個元素是HTML頁面中顯示給我們看的名稱,我們之後的項目會用到這一欄位。例如:
from django.db import modelsLEVLES = (('1', 'Very Good'), ('2', 'Good'), ('3', 'Normal'), ('4', 'Bad'),)class Comment(models.Model): id = models.AutoField(primary_key=True) levels = models.CharField(max_length=1, choices=LEVELS)
help_text:HTML頁面中輸入控制項的幫助字符串unique:如果為True,代碼此欄位在整個表中是唯一的。...總結
到此,我們花了大量的時間來介紹Django的模型的基本結構、欄位類型、欄位參數,其實Django遠遠不止這些欄位。現在很多我們用不上,沒關係,等需要用到的時候查看官方文檔使用相應功能。
Django團隊為我們考慮到這麼多需要用到的功能,可能看到這大家都有點累了,反而我們能認識到Django這一框架的強大功能。