Django ORM框架
思考:Django操作資料庫中的資料(增刪改查),都有哪些方式可以實現呢?
首先,肯定能想到的方式一:使用三方資料庫操作模組,執行原生的sql語句對資料庫進行操作,如pymysql模組,但此種方式勢必存在以下問題:
1. sql語句一般比較複雜,並且維護困難
2. sql語句的安全性無法得到保障,可能會有sql注入的風險
3. 資料庫的建立、資料表的生成、資料備份以及資料庫的遷移非常麻煩
4. sql語句效能無法保障
其次,方式二就是本篇文章主要要說的:通過ORM框架操作資料庫
在介紹ORM框架之前,先看看mysql都有哪些物件?
1. 資料庫
2. 資料表
3. 欄位
4. 記錄
那麼,ORM框架與這些物件又有什麼關係?
1. 資料庫 --> 需要提前手動建立資料庫
2. 資料表 --> 與ORM框架中的模型類一一對應
3. 欄位 --> 與ORM框架中模型類的類屬性一一對應
4. 記錄 --> 與ORM框架中模型類的例項一一對應
在通過ORM框架操作資料庫之前,需要對使用的資料庫進行配置:
1. 在全域性配置檔案settings.py的DATABASES字典中配置需要連線的資料庫資訊
2. Django預設使用的資料庫是sqlite3(關係型文字資料庫)
3. 資料庫配置格式如下:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } }
注:
default 為資料庫的別名(標籤)
ENGINE 指定資料庫引擎,Django預設支援5種資料庫引擎:mysql、oracle、postgresql、postgresql_psycopg2,如果要使用其他的資料庫,如redis、mongo等,需要安裝對應的模組後再另行配置,此處不展開。
NAME 指定資料庫名稱,如果使用的是sqlite3,需要自定sqlite3檔案的絕對路徑
4. 配置mysql資料庫資訊示例:
DATABASES = {'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mysqlDB', 'USER': 'root', 'PASSWORD': '123456', 'PORT': 3306, 'HOST': '127.0.0.1' } }
方便起見,我用的是Django預設資料庫sqlite3,配置資訊沒有更改
PS:使用編輯器pycharm連線sqlite資料庫示例
配置完資料庫資訊,就可以定義模型類了:
1. 一般在子應用的models.py檔案中定義模型類(相當於資料庫中的一張表)
2. 模型類必須繼承Model或者Model的子類
3. 模型類中定義的類屬性(相當於資料表中的欄位),必須是Field的子類
class Projects(models.Model): name = models.CharField(max_length=50, verbose_name="專案名稱", help_text="專案名稱", unique=True) leader = models.CharField(max_length=10, verbose_name="專案負責人", help_text="專案負責人") is_execute = models.BooleanField(verbose_name="是否啟動專案", help_text="是否啟動專案", default=True) desc = models.TextField(verbose_name="專案描述資訊", help_text="專案描述資訊", null=True, blank=True, default='') create_time = models.DateTimeField(verbose_name="建立時間", help_text="建立時間", auto_now_add=True) update_time = models.DateTimeField(verbose_name="更新時間", help_text="更新時間", auto_now=True) class Meta: db_table = "tb_projects"
4. 定義類屬性時,常用的Field子類:
1)CharField --> varchar
2)IntegerField--> integer
3)BooleanField--> bool
4)TextField--> longtext
5)DateTimeField--> datetime
......
5. 定義類屬性時,field子類常用options:
1)verbose_name:admin後臺中該欄位的別名
2)help_text:通過表單小部件來展示該欄位額外的help資訊,值一般與verbose_name保持一致即可
3)unique:該欄位設定唯一約束,預設值為False
4)default:為該欄位設定預設值
5)blank:該欄位是否允許前端傳遞空字串,預設值為False
6)null:該欄位是否允許前端傳遞null,預設值為False
7)auto_now:DateTimeField的例項引數,儲存資料時該欄位值會自動儲存為當前時間,每次執行save方法時都會將當前時間儲存
8)auto_now_add:DateTimeField的例項引數,建立資料時該欄位值會自動儲存為當前時間,之後更新資料該欄位值不會再更新
6. 可以在任意一個模型類中定義Meta內部類,用於修改資料庫的元資料資訊,如:
1)在Meta內部類中,定義類屬性 db_table 的值,即為該模型類對應生成的資料表的表名;
2)在Meta內部類中,定義類屬性 verbose_name 的值,即為該模型類對應生成的資料表的描述資訊;
3)在Meta內部類中,定義類屬性 abstract=True ,指定當前模型類為抽象模型類,在遷移時不會生成資料表;
4)在Meta內部類中,定義類屬性 ordering=['欄位名'] ,指定該模型類對應生成的資料表資料的排序欄位,預設按照id排序
7. 表與表之間的關聯關係的定義:
1)ForeignKey --> 一對多,一般在‘多’的那個模型類中定義外來鍵欄位,如:一個專案會有多個介面,一般在介面表中定義外來鍵欄位
必傳引數:to ,即和誰建立外來鍵關係,有三種傳值方式:
第一種:匯入要建立外來鍵關係的模型類(一般稱為主表模型類),傳遞該模型類的引用;
第二種:字串,子應用名.模型類名,此種方式無需匯入
第三種:字串,self,表示自關聯(自己關聯自己)
必傳引數:on_delete ,即指定主表資料刪除後,從表資料的刪除策略
model.CASCADE 主表資料刪除後,相應的從表資料也刪除
model.SET_NULL 主表資料刪除後,相應的從表資料設定為null,前提:從表字段必須設定null=True
model.SET_DEFAULT 主表資料刪除後,相應的從表資料設定為預設值,前提:從表字段必須設定預設值default=xx
model.PROTECT 主表資料刪除時,如果從表有對應的資料,則會報錯
class Interfaces(models.Model): name = models.CharField(max_length=50, verbose_name="介面名稱", help_text="介面名稱", unique=True) tester = models.CharField(max_length=10, verbose_name="測試人員", help_text="測試人員") desc = models.TextField(verbose_name="介面描述資訊", help_text="介面描述資訊", null=True, blank=True, default='') create_time = models.DateTimeField(verbose_name="建立時間", help_text="建立時間", auto_now_add=True) update_time = models.DateTimeField(verbose_name="更新時間", help_text="更新時間", auto_now=True) projects = models.ForeignKey("projects.Projects", on_delete=models.CASCADE, verbose_name="所屬專案", help_text="所屬專案") class Meta: db_table = "tb_interfaces" verbose_name = "介面表" verbose_name_plural = "介面表"
2)ManyToManyField --> 多對多,可以在任意一個模型類中使用ManyToManyField
3)OneToOneField --> 一對一,可以在任意一個模型類中使用OneToOneField
8. Django模型類轉化為資料表
1)生成遷移指令碼:進入專案虛擬環境,執行命令 python manage.py makemigrations 子應用名
注:如果不指定子應用名,會把所有子應用都生成遷移指令碼
檢視生成的遷移指令碼內容,如下圖
注:定義模型類時,未定義主鍵,預設會自動建立一個名為id的自增主鍵。
2)執行遷移指令碼:進入專案虛擬環境,執行命令 python manage.py migrate 子應用名
注:生成的資料表名預設為:子應用名_模型類名小寫;如果內部類Meta中定義了db_table屬性,則資料表名為db_table的值
對定義了外來鍵欄位的模型類進行遷移,並檢視生成的資料表中外來鍵欄位的顯示
外來鍵欄位名顯示為:模型類中定義的外來鍵欄位名_id
可以使用命令 python manage.py sqlmigrate 子應用名 遷移指令碼名 來檢視遷移指令碼生成的sql語句
9. BaseModel的定義:
1)目的:精簡模型類程式碼,將公共欄位抽取出來,定義在BaseModel中,需要用到公共欄位的模型類,繼承BaseModel即可
2)BaseModel 沒有必要生成資料表,需要在定義BaseModel時,在其內部類Meta中設定abstract=True,即表明當前模型類為抽象模型類,遷移時不會建立表,僅僅用於其他模型類繼承
3)位置:一般會建立utils包,將BaseModel定義在此包中
本部落格僅為本人學習過程中的記錄,歡迎一起交流經驗。