6、Models模型操作
1 ORM概述
- 介紹
- Django對數據進行增刪改操作是借助內置的ORM框架(Object Relational Mapping,對象關系映射)所提供的API方法實現的,允許你使用類和對象對數據庫進行操作,從而避免通過SQL語句操作數據庫。
- 簡單來說,ORM框架的數據操作API是在 QuerySet 類中定義的,由開發者自定義模型對象調用 QuerySet類,來實現數據的操作。
- 作用
- 建立模型類和表之間的對應關系,允許我們通過面向對象的方式來操作數據庫。
- 根據設計的模型類生成數據庫中的表格。
- 通過簡單的配置就可以進行數據庫的切換。
- 好處
- 只需要面向對象編程, 不需要面向數據庫編寫代碼.
- 對數據庫的操作都轉化成對類屬性和方法的操作.
- 不用編寫各種數據庫的sql語句.
- 實現了數據模型與數據庫的解耦, 屏蔽了不同數據庫操作上的差異.
- 不在關注用的是mysql、oracle…等數據庫的內部細節.
- 通過簡單的配置就可以輕松更換數據庫, 而不需要修改代碼.
- 只需要面向對象編程, 不需要面向數據庫編寫代碼.
- 缺點
- 對于復雜業務,使用成本較高
- 根據對象的操作轉換成SQL語句,根據查詢的結果轉化成對象, 在映射過程中有性能損失.
- ORM 示意
1、增加數據
- 為了演示 Django項目的增刪改操作,可以使用 Django 的 shell 模式(啟動命令行和執行腳本)進行講述,該模式方便開發人員開發與調試程序。
- 在Terminal中開啟Shell模式,執行命令:
python manage.py shell
,演示示例:
1 新增數據
(base) PS C:\ProjectManager\tianfu\babys> python .\manage.py shell
11 objects imported automatically (use -v 2 for details).Python 3.12.4 | packaged by Anaconda, Inc. | (main, Jun 18 2024, 15:03:56) [MSC v.1929 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.25.0 -- An enhanced Interactive Python. Type '?' for help.from commodity.models import Types, CommodityInfos# 1 基本數據添加方法
# 方法1:創建對象,給對象的屬性賦值,調用save方法保存
t1 = Types()
t1.firsts = '兒童服飾';
t2.seconds = "女裝"
t1.seconds = "女裝"
t1.save()# 方法2:創建對象時,為對象的屬性賦值,調用save方法保存
t2 = Types.objects.create(firsts="兒童教育", seconds="python書籍")
t2.save()# 方法3: 通過對象的objects下的create方法
t3 = Types.objects.create(firsts="兒童用品", seconds="搖搖車")
t3.save()# 方法3: 通過對象的objects下的create方法[參數較多時,可使用字典構建,在拆解]
t4_dict = {'firsts': '兒童用品', 'seconds': '早教機', 'add_time': '2025-02-12 11:08:08'}
t4 = Types.objects.get_or_create(**t4_dict)
2 獲取添加
-
在執行數據新增時,為了保證數據的有效性,需要對數據進行去重判斷,以確保數據不會重復新增:
-
方案1:對數據表進行查詢,如果查詢結果不存在,則執行新增數據。
-
方案2:Django提供 get_or_create() 方法 (推薦)
# 對應的SQL語句: # SELECT * FROM commodity_types WHERE firsts = '童裝' AND seconds = '男裝'; # INSERT INTO commodity_types (firsts, seconds) VALUES ('童裝', '男裝'); t5_dict = dict(firsts='兒童服裝', seconds='男裝') t5 = Types.objects.get_or_create(**t5_dict) t5 # 返回元組:(<Types: 22>, True),第一個參數表示新建的對象,第二個參數表示操作的結果 t5[0].firsts # '兒童服裝' t5[0].seconds # '男裝't5_dict = dict(firsts='兒童服裝', seconds='潮牌') t5 = Types.objects.get_or_create(**t5_dict) t5 t5[0].seconds
- 說明
- get_or_create 根據每個模型字段的值與數據表的數據進行判斷:
- 只要有一個模型字段的值與數據表的數據不相同(除主鍵以外),就會執行新增數據操作。
- 如果每個模型字段的值與數據表的某行數據完全相同,則就不執行新增,反而返回這個這行數據的數據對象。
- get_or_create 根據每個模型字段的值與數據表的數據進行判斷:
- 說明
-
3 更新添加
-
Django中還提供了 update_or_create 方法,用于判斷當前數據在數據表中是否存在,若存在則執行更新操作,否則在數據表中新增數據。
# 對應的SQL語句: # SELECT * FROM commodity_types WHERE firsts = '兒童早教' AND second = '兒童玩具'; # UPDATE commodity_types SET third = NULL, addtime = NOW() WHERE id = 5; --存在 # INSERT INTO commodity_types (firsts, second, third, addtime) VALUES ('兒童早教', '兒童玩具', NULL, NOW()); -- 不存在In [26]: d4 = dict(firsts="兒童早教", second="兒童玩具") In [27]: t4 = Types.objects.update_or_create(**d4)In [28]: t4 Out[28]: (<Types: 22>, True)In [29]: t4 = Types.objects.update_or_create(**d4) In [30]: t4 Out[30]: (<Types: 22>, False)In [31]: t4[0].id Out[31]: 22
4 批量新增
-
如果想要對某個模型執行數據批量新增操作,則可以使用 bulk_create 方法實現,只需要就愛那個數據對象以列表或元組的形式傳入 bulk_create 方法:
# 對應的SQL語句:INSERT INTO commodity_types (firsts, second, third, addtime) VALUES ('兒童用品', '濕紙巾', NULL, NOW()), ('兒童用品', '紙尿褲', NULL, NOW());In [32]: t5 = Types(firsts="兒童用品", second="濕紙巾") In [33]: t6 = Types(firsts="兒童用品", second="紙尿褲") In [34]: obj_lists = [t5, t6] In [35]: Types.objects.bulk_create(obj_lists) Out[35]: [<Types: None>, <Types: None>]
-
在使用 bulk_create 方法前,數據類型為模型Types的實例化對象,并且在實例化過程中設置每一個字段的值,最后將所有實例化對象存放在列表或元組中,以參數的形式傳遞給 bulk_create 方法,從而實現數據批量化的新增操作。
2、更新數據
-
更新數據操作與新增數據步驟大致相同,唯一的區別就在于數據對象來自數據表,需要執行一次數據查詢,查詢的結果以對象的形式表示,并將對象的屬性進行賦值處理。
# 方法1:查詢單條數據后更新 # 對應SQL語句: # SELECT * FROM commodity_types WHERE id = 11; # UPDATE commodity_types SET firsts = '兒童用品', third = NULL WHERE id = 11;In [36]: t = Types.objects.get(id=11) In [37]: t.firsts = "兒童用品" In [38]: t.save()In [39]: t.firsts Out[39]: '兒童用品'# 方法2:批量更新一條或多條數據 # 查詢方式使用 filter:以列表的形式返回,查詢結果可能是一條或多條# 對應的SQL語句:UPDATE commodity_types SET second = '濕紙巾褲' WHERE id = 23; In [40]: t = Types.objects.filter(id=23) In [41]: t Out[41]: <QuerySet [<Types: 23>]>In [42]: t.update(sencond='濕紙巾褲') Out[42]: 1# 更新數據以字典格式表示 # 對應的SQL語句:UPDATE commodity_types SET second = '童鞋' WHERE id = 23; In [43]: d = dict(second='童鞋') In [44]: Types.objects.filter(id=23).update(**d)# 方法3:不查詢直接修改:默認是對全表的數據進行更新 # 對應的SQL語句:UPDATE commodity_types SET firsts = '母嬰用品'; In [44]: Types.objects.update(frists="母嬰用品")# 方法4:對數據某列自增或自減 # 對應SQL語句:UPDATE commodity_types SET id = id + 10 WHERE id = 23; In [