上片文章講解模板。你本文將講解 “MTV” 中 M 層次泌类,即模型層(數(shù)據(jù)存取層)。模型這內(nèi)容比較多底燎,我將其拆分為 3 個部分來講解刃榨。同時,文章也配套了例子双仍,你可以通過 閱讀原文 來查看枢希。
0 編程環(huán)境
因為 Django 近期推出 Django 2.0 版本, 所以有必要再說明下殊校。如果你是按照本系列來學習 Django 框架的話晴玖,按照前面安裝 Django 的方式,你安裝 Django 版本應該是最新版本为流,即 2.0呕屎。
那么使用最新 Django 版本來學習可以嗎?如果是學習的話敬察,不用太在意版本秀睛。當然學習最新的較好,因為可以學習新的 API莲祸。同時蹂安,Django 2.0 不再兼容 Python 2 了,現(xiàn)在學習 Python 都建議采用 Python 3版本了锐帜。另外 Django 1.8 官方只維護到 2018 年的 4 月田盈,1.11 是最后一個兼容 Python 2 的 Django版本。如果是項目需要升級 Django版本缴阎,需要兼容到 Python 2允瞧,那么要考慮用 1.11 版本了。
順便補充下本文用的一些工具的版本:Python 版本是 3.6,Mysql 版本是 5.5.
1 模型是什么
在 Web 應用中述暂,數(shù)據(jù)一般存儲到數(shù)據(jù)庫中痹升。Django 中的模型層是跟數(shù)據(jù)庫打交道的層次。模型層中可能會有多個模型畦韭,每個模型(每個 app 中的 models.py 中每個類都是一個模型)都對應著數(shù)據(jù)庫中的唯一一張表疼蛾。
2 配置數(shù)據(jù)庫
在我們探索 Django 的模型層之前,我們需要配置下數(shù)據(jù)庫艺配;告訴 Django 視野什么數(shù)據(jù)庫以及如何連接數(shù)據(jù)庫察郁。這一步要確保配置無誤,不然后面難以執(zhí)行妒挎。我們找到新項目中的 setting.py, 里面有個 DATABASES 選項绳锅。Django 默認是使用 sqlite 數(shù)據(jù)庫,所以你會看到里面 sqlite 數(shù)據(jù)庫的配置信息酝掩。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
上面的代碼中的 ENGINE 是選擇哪個數(shù)據(jù)庫引擎, NAME 是數(shù)據(jù)庫的名字鳞芙。至于選擇哪種引擎,要看項目中使用了什么數(shù)據(jù)庫期虾。Django 目前支持以下這 MySQL原朝、PostgreSQL、Oracle 等數(shù)據(jù)庫镶苞,它們的數(shù)據(jù)庫引擎設置如下:
設置字段 | 數(shù)據(jù)庫 | 設配器(驅(qū)動) |
---|---|---|
postgresql | PostgreSQL | psycopg 1.x版 |
postgresql_psycopg2 | PostgreSQL | psycopg 2.x版 |
mysql | MySQL | MySQLdb |
sqlite3 | SQLite | 不需要 |
oracle | Oracle | cx_Oracle |
其中設置字段是填充 ENGINE 的值喳坠。如果你使用的 MySQL 數(shù)據(jù)庫,那么你需要填寫 django.db.backends.mysql茂蚓。數(shù)據(jù)庫驅(qū)動表示需要使用 pip 安裝該庫壕鹉。如果你使用的 MySQL 數(shù)據(jù)庫,那么你需要安裝 MySQLdb 設配器聋涨。
但是這里有個坑晾浴,MySQLdb 在支持 Python 2 版本,不支持 Python 3 版本牍白。所以你安裝該設配器之后脊凰,運行項目會報出錯誤。Django 官網(wǎng)建議使用替代品 mysqlclient茂腥。mysqlclient 是 MySQLdb 的一個分支狸涌,最主要是它支持 Python 3。
本文中使用到 Mysql 數(shù)據(jù)庫最岗,那么 DATABASES 的配置如下:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django',
'HOST': '127.0.0.1',
'PORT': '3306',
'USER': 'root',
'PASSWORD': '123456',
}
}
3 第一個模型
我們先新建名為 Django_demo 的 projeact, 再新建名為 demo 的 app帕胆。最后,別忘記在 setting.py 中將新創(chuàng)建的 app 激活般渡。
# Django 2.0 的初始配置內(nèi)容
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'demo', # 我們新創(chuàng)建的 app
]
3.1 創(chuàng)建模型
打開我們剛才創(chuàng)建的 app 中的 models.py 文件惶楼,我們以后就主要在這里編寫模型右蹦。假設現(xiàn)在有個需求:某個作者創(chuàng)作了一本書,本書由出版社出版了歼捐。我們可以設定三者的字段以及關(guān)系。
- 假設作者有姓名晨汹、Email 郵箱這兩個數(shù)據(jù)屬性豹储。
- 假設出版社有出版社名稱、地址這兩個屬性淘这。
- 書籍有兩四個屬性:書名剥扣、出版日期、作者铝穷、出版社。有一個或多個作者(和作者是多對多的關(guān)聯(lián)關(guān)系[many-to-many])曙聂, 只有一個出版商(和出版商是一對多的關(guān)聯(lián)關(guān)系[one-to-many],也被稱作外鍵[foreign key])
所以我們編寫代碼如下:
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=40)
email = models.EmailField()
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
# publisher = models.ForeignKey(Publisher)
# Django 2.0 需要加上 on_delete=models.CASCADE
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
publication_date = models.DateField()
我們定義每個模型断国,即類(如 Author 和 Book)都需要繼承 django.db.models.Model。Model 是 Django 做了一層包裝以便我們更加方便地使用的類榆苞, 它其中包含了所有數(shù)據(jù)庫交互的方法。上面代碼中的每個類相當于單個數(shù)據(jù)庫表坐漏,每個屬性也是這個表中的一個字段。 屬性名就是字段名赊琳,它的類型(例如 CharField )相當于數(shù)據(jù)庫的字段類型 (例如 varchar )街夭。例如, Publisher 模塊等同于下面這張表
CREATE TABLE "Publisher" (
"id" serial NOT NULL PRIMARY KEY,
"name" varchar(30) NOT NULL,
"address" varchar(50) NOT NULL,
);
所以我們在為屬性命名的時候慨畸,要避免使用數(shù)據(jù)庫的關(guān)鍵字。另外檐什,我們只需要關(guān)心每個類的屬性以及長度限制弱卡,不用關(guān)心怎么創(chuàng)建數(shù)據(jù)庫表。Django 可以自動生成這些 CREATE TABLE 語句的瓮具。
3.1 創(chuàng)建數(shù)據(jù)表
我們上面的創(chuàng)建了幾個模型還處于定義上,Django 還沒有正真創(chuàng)建數(shù)據(jù)庫中的表名党。
因此传睹,我們需要執(zhí)行兩個命令來同步一下數(shù)據(jù)庫。
在我們剛才創(chuàng)建的工程 Django_demo 目錄下欧啤,我們打開終端邢隧,執(zhí)行以下命令:
python manage.py makemigrations
運行成功效果圖如下:
這一步相當于 在該app下建立 migrations目錄,并記錄下你所有的關(guān)于modes.py的改動按摘,比如0001_initial.py迫靖, 但是這個改動還沒有作用到數(shù)據(jù)庫文件
第二步,在之前的終端上繼續(xù)執(zhí)行 migrate 命令系宜。
python manage.py migrate
運行成功效果圖如下:
這一步表示將該改動(當makemigrations之后產(chǎn)生了0001_initial.py 文件)作用到數(shù)據(jù)庫文件盹牧,比如 create table 之類。
如果你用到 Pycharm 的 Database 功能汰寓,你會看到我們剛才創(chuàng)建的定義的幾個模型有滑。
3.2 字段類型
在前面的例子中,我們需要對每個屬性設置一個字段望艺,例如 CharField肌访。Django 內(nèi)置了幾十種內(nèi)置字段類型。常用的類型如下:
- AutoField:一個根據(jù)實際ID自動增長的 IntegerField 惩激。如果表中沒有設置主鍵時,將會自動添加一個自增主鍵顷蟀。
2)IntegerField:一個整數(shù)。在 Django 所有支持的數(shù)據(jù)庫中哮兰,-2147483648 到 2147483647 范圍才是合法的喝滞。
3)BigIntegerField:一個64位整數(shù), 和 IntegerField 類似右遭,不過它的范圍比較大缤削。
4)BooleanField:一個 true/false 字段亭敢。這個字段的默認表單部件是 CheckboxInput。
5)CharField:字符字段帅刀。對于比較大的文本內(nèi)容,請使用 TextField 類型扣溺。這個字段的默認表單部件是 TextInput。它有個參數(shù) max_length腹纳。max_length 表示字段允許的最大字符串長度驱犹。這將在數(shù)據(jù)庫中和表單驗證時生效
6)TextField:大文本字段。默認的表單部件是一個 Textarea蛔钙。
7)DateField:日期荠医。它帶有兩個可選參數(shù):auto_now 和 auto_now_add桑涎。auto_now 表示當對象保存時兼贡,該字段會自動設置成當前時間。一般用于記錄“修改時間” 等曼。auto_now_add 記錄字段首次被創(chuàng)建的時間凿蒜。
8)DateTimeField:時間和日期。它也帶有兩個可選參數(shù)州泊,名字和用法跟 DateField 一樣漂洋。
9)TimeField:時間字段, 類似于Python datetime.time 實例. 和 DateField 具有相同的選項刽漂。
10)URLField:一個 CharField 類型的URL,默認長度是200贝咙;默認的表單部件是一個 TextInput颈畸。
11)EmailField:一個檢查輸入的email地址是否合法的 CharField 類型。
12)FileField:上傳文件字段礁苗。
13)ImageField:圖片字段徙缴,它繼承了 FileField 所以屬性和方法。
3.3 關(guān)系字段
關(guān)系字段(Relationship fileds) 也是屬于字段疏叨,只不過三個字段比較特殊穿剖,所以單獨拿出來說糊余。我們按照上述的創(chuàng)建模型的例子來繼續(xù)講解单寂。它們?nèi)咧g的關(guān)系應該這樣:一本書由一家出版社出版吐辙,一家出版社可以出版很多書。一本書由多個作者合寫尊沸,一個作者可以寫很多書贤惯。
1)ForeignKey
表示屬于模型間關(guān)系中的多對一關(guān)系孵构。在我們的范例模型中,一家出版社 publisher 可以出版很多書 Book。在數(shù)據(jù)庫中, Django 使用 ForeignKey 字段名稱+ "_id" 做為數(shù)據(jù)庫中的列名稱溯职。在上面的例子中, 書籍 model 對應的數(shù)據(jù)表中會有一個 publisher_id 列谜酒。你可以通過顯式地指定 db_column 來改變該字段的列名稱,不過,除非你想自定 義 SQL 粘驰,否則沒必要更改數(shù)據(jù)庫的列名稱述么。
它第一個參數(shù)必須傳入該模型關(guān)聯(lián)的類度秘。on_delete 現(xiàn)在可以用作第二個位置參數(shù)(之前它通常只是作為一個關(guān)鍵字參數(shù)傳遞). 在Django 2.0中,這將是一個必傳的參數(shù)剑梳。
2)OneToOneField
它屬于 ForeignKey 中的特例垢乙。當 ForeignKey 中有個字段 unique 被設置為 True 時, 就表示一對一關(guān)系酪刀。
3)ManyToManyField
屬于模型間關(guān)系中的多對多關(guān)系。在我們的范例模型中齐婴, Book 有一個 多對多字段 叫做 authors稠茂。因為他們的關(guān)系是一本書由多個作者合寫睬关,一個作者可以寫很多書。在數(shù)據(jù)庫中
Django 創(chuàng)建一個中間表來表示 ManyToManyField 關(guān)系丐箩。默認情況下,中間表的名稱由兩個關(guān)系表名結(jié)合而成施籍。所以剛才我們創(chuàng)建數(shù)據(jù)庫表的途中概漱,會有四張表瓤摧,而不是三表。
3.4 字段選項
有些字段會有些特殊參數(shù)腻异,但所有字段類型都又些通用的可選選項这揣。先是常用的可選選項。
1)null :如果該參數(shù)設置為 True这嚣,Django將會把數(shù)據(jù)庫中的空值保存為 NULL姐帚。不填寫就默認為 False障涯。
2)blank:如果為 True 膳汪,該字段允許為空值九秀,不填寫默認為 False鼓蜒。這個字段是用于處理表單數(shù)據(jù)輸入驗證。
3)primary_key:如果為 True娇豫,那么這個字段就是模型的主鍵畅厢。
4)unique:如果該值設置為 True, 這個數(shù)據(jù)字段在整張表中必須是唯一的框杜。
5)default:設置該字段的默認值。
6)由二項元組構(gòu)成的一個可迭代對象(列表或元組)椒振,用來給字段提供選擇項梧乘。 如果設置了 choices选调,默認的表單將是一個選擇框灵份。具體使用例子如下:
from django.db import models
class Person(models.Model):
SHIRT_SIZES = (
('S', 'Small'),
('M', 'Medium'),
('L', 'Large'),
)
name = models.CharField(max_length=60)
shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)
下篇文章填渠,我們將講解如果對這些模型(表)進行操作。
源碼地址
4 寫在最后
我新建一個 Python Web 學習交流 QQ 群莺葫,群號:701534112枪眉。歡迎大家加群,一起交流堡纬,一起學習烤镐,一起進步。
往前 Django 學習筆記文章
Django 學習筆記之環(huán)境搭建
Django 學習筆記之初始
Django 學習筆記之視圖與URL配置
Django 學習筆記之模板
本文原創(chuàng)發(fā)布于微信公眾號「極客猴」碗旅,歡迎關(guān)注第一時間獲取更多原創(chuàng)分享