一、🚀 ORM 新增數據魔法!
核心目標
教你用?Django ORM?給數據庫?新增數據?!就像給數據庫 “生小數據寶寶”👶
方法 1:實例化 Model + save(一步步喂數據)
obj = Feedback() # 實例化
obj.quality = data['quality'] # 指定數據
obj.attitude = data['attitude']
obj.speed = data['speed']
obj.text = data['text']
obj.anonymous = data['anonymous']obj.save() # 入庫
1.?obj = Feedback()
?→ 造一個空數據盒子
Feedback
?是模型類(模具),obj
?是用模具做的?空數據模型?~- 類比:用 “Feedback 模具” 捏一個空白小泥人,準備填數據~
2.?obj.quality = data['quality']
?→ 給盒子填數據
- 從?
data
?字典里,把?quality
(商品質量)的值,塞給?obj
?的?quality
?字段~ - 后面幾行同理:依次填?
attitude
(客服態度)、speed
(物流速度)、text
(評論)、anonymous
(是否匿名)~ - 類比:給小泥人畫眼睛、穿衣服、寫名字… 每個屬性都從?
data
?里選材料~
3.?obj.save()
?→ 把盒子存進數據庫
- 填完所有數據后,調用?
save()
?方法,Django 會把?obj
?轉換成?數據庫的一條記錄?,永久保存! - 類比:把捏好、畫好的小泥人,放進 “數據庫展示柜” 里~
方法 2:類方法 create(一鍵批量填數據)
Feedback.objects.create(**data)
1.?Feedback.objects
?→ 模型的 “數據管家”
objects
?是 Django 模型默認的?管理器?,負責和數據庫交互(增刪查改)~- 類比:
Feedback
?模型的 “專屬小管家”,幫你處理數據操作~
2.?.create(**data)
?→ 一鍵創建 + 保存
create
?是管家提供的 “快捷魔法”:自動幫你?實例化模型 + 填數據 + 保存入庫?!**data
?是把?data
?字典 “拆包”,把里面的鍵值對(如?quality=5
、text="好評"
?)傳給?create
?方法~- 類比:告訴小管家?
data
?里的所有材料,它會自動用 “Feedback 模具” 捏好小泥人,直接放進展示柜!
3. 和方法 1 的區別
- 方法 1 是?手動一步步填數據?,適合需要 “填數據前做額外操作” 的場景(比如給某個字段加默認值、校驗)。
- 方法 2 是?一鍵批量操作?,適合數據已經準備好,直接入庫的場景,代碼更簡潔~
總結(小劇場對比)
方法 1 小劇場
你:管家!我要存一條反饋數據~
管家:好呀!先拿一個空盒子(Feedback()
?)~
你:給盒子填質量、態度、速度…(手動賦值)
你:填好啦!放進展示柜(save()
?)~
方法 2 小劇場
你:管家!我要存一條反饋數據,材料都在?data
?里~
管家:收到!自動用模具捏好、填數據、放進展示柜(create(**data)
?)~
兩種方法都能給數據庫新增數據,根據場景選就行啦~ 方法 1 靈活可控,方法 2 快捷方便! 🎉
(比如需要校驗數據、加默認值 → 選方法 1;數據直接能用 → 選方法 2~)
二、🎯 Django ORM 修改數據?
核心目標
教你用?Django ORM?給數據庫?修改已有數據?!就像給數據庫里的 “數據寶寶” 換衣服~ 👚
方法 1:修改實例對象(一步步改)
# 1. 獲取數據
obj: Feedback = Feedback.objects.get(id=5) # 獲取ID=5的數據
print(f"{obj=}, {obj.text}")# 2. 修改字段
obj.text = "7777"# 3. 保存修改
obj.save() # 重新入庫
print(f"{obj=}, {obj.text}")
1.?obj = Feedback.objects.get(id=5)
?→ 找到要改的數據
Feedback.objects
?是模型的 “數據管家”,get(id=5)
?是讓管家?找到 “ID=5” 的數據?,賦值給?obj
?~- 類比:你對管家說 “把展示柜里 ID=5 的小泥人拿出來”,管家找到后給你~
2.?print(...)
?→ 看看原來的數據
- 打印?
obj
?和?obj.text
?,看看修改前的數據長啥樣~ - 類比:拿到小泥人后,先看看它原來的衣服、裝飾~
3.?obj.text = "7777"
?→ 給數據換 “新衣服”
- 把?
obj
?的?text
?字段改成?"7777"
?,其他字段不變~ - 類比:給小泥人換一件新衣服(只改?
text
?,其他裝飾保留)~
4.?obj.save()
?→ 把修改后的數據放回數據庫
- 調用?
save()
?,Django 會把修改后的?obj
?重新存回數據庫,覆蓋原來的數據~ - 類比:給小泥人換好新衣服后,放回展示柜(數據庫)~
5. 再?print(...)
?→ 看看修改后的數據
- 打印修改后的?
obj
?和?obj.text
?,確認修改生效~ - 類比:放回展示柜前,再檢查一下小泥人的新衣服~
方法 2:調用類方法 update(批量改)
Feedback.objects.update(text="888")
1.?Feedback.objects
?→ 模型的 “數據管家”
- 還是那個 “專屬小管家”,負責和數據庫交互~
2.?.update(text="888")
?→ 批量修改數據
update
?是管家提供的 “批量魔法”:?把所有數據的?text
?字段改成?"888"
?!- 注意:這會修改?所有數據?的?
text
?字段(如果想改指定數據,需要加過濾條件,比如?filter(id=5).update(...)
?)~ - 類比:你對管家說 “把展示柜里所有小泥人的衣服都換成?
text="888"
?樣式”,管家會批量操作!
3. 和方法 1 的區別
- 方法 1 是?“先找到數據 → 修改 → 保存”?,適合改?單條數據?,還能在修改前做額外操作(比如打印、校驗)。
- 方法 2 是?“直接批量改”?,適合改?多條數據?,代碼更簡潔,但要注意過濾條件(否則會改全部)~
總結(小劇場對比)
方法 1 小劇場
你:管家!把 ID=5 的小泥人拿出來~
管家:好的!(get(id=5)
?)
你:給它換件新衣服?text="7777"
?~
你:檢查一下(print
?),沒問題!放回展示柜(save
?)~
方法 2 小劇場
你:管家!把所有小泥人的衣服都換成?text="888"
?~
管家:收到!批量操作完成(update
?)~
兩種方法都能修改數據,根據場景選就行啦~ 方法 1 適合改單條、需要校驗的場景;方法 2 適合批量改、追求簡潔的場景~ 🚀
(注意:方法 2 如果不加?filter
?,會修改?所有數據?,用的時候要小心哦!)
三、🕵??♀? Django ORM 查詢魔法?
核心目標
教你用?Django ORM?從數據庫里?“撈數據”?!不管是找單條、多條,還是帶條件篩選,都能輕松拿捏~
“撈數據” 的基本姿勢(獲取對象)
1. 獲取單個對象(精準定位)
obj: Feedback = Feedback.objects.get(id=5) # 獲取ID=5的數據
拆解:
Feedback.objects
:模型的 “數據管家”,負責和數據庫嘮嗑~.get(id=5)
:管家接到指令 → 去數據庫找?“ID=5” 的那條數據?,找到后包裝成?Feedback
?對象給你~- 類比:你對管家說 “把展示柜里 ID=5 的小泥人拿過來”,管家精準找到遞給你~
?? 注意:如果?get
?沒找到數據,會報錯?DoesNotExist
?;如果找到多條,會報錯?MultipleObjectsReturned
?。所以適合?確定只有一條數據?的場景~
2. 獲取多個數據(批量撈)
① 獲取全部數據
obj_list: list[Feedback] = Feedback.objects.all() # 獲取全部數據
.all()
:管家接到指令 → 把數據庫里?所有 Feedback 數據?都撈出來,包裝成列表給你~- 類比:你對管家說 “把展示柜里所有小泥人都拿過來”,管家抱來一整箱~
② 獲取部分數據(帶條件篩選)
obj_list: list[Feedback] = Feedback.objects.filter(id=5) # 獲取部分數據
.filter(id=5)
:管家接到指令 → 去數據庫找?“ID=5” 的所有數據(雖然 ID 一般唯一,但語法支持找多個 ),包裝成列表給你~- 類比:你對管家說 “把展示柜里 ID=5 的小泥人都拿過來”(如果有多個重名 ID ,就都抱來 )~
③ 獲取指定范圍數據
obj_list: list[Feedback] = Feedback.objects.all()[:100] # 獲取指定范圍數據
.all()[:100]
:先撈全部數據,再?切片取前 100 條?~- 類比:你對管家說 “把展示柜里的小泥人都拿過來,我只看前 100 個”,管家抱來一箱,你自己挑前 100 個~
條件查詢(精準篩選的魔法語法)
Django ORM 提供了超方便的?條件查詢語法?,用?__
(雙下劃線)實現各種篩選!
條件 | 語法 | 例子(找 quality 字段) | 含義 |
---|---|---|---|
等于 | = | filter(quality=5) | quality 等于 5 |
大于 | __gt | filter(quality__gt=3) | quality 大于 3 |
大于等于 | __gte | filter(quality__gte=3) | quality 大于等于 3 |
小于 | __lt | filter(quality__lt=3) | quality 小于 3 |
小于等于 | __lte | filter(quality__lte=3) | quality 小于等于 3 |
包含(在列表里) | __in | filter(quality__in=[1,3,5]) | quality 是 1、3、5 中的一個 |
不等于 | exclude | exclude(quality=5) | quality 不等于 5 |
舉個栗子🌰
比如想找?“quality 大于 3”?的數據:
obj_list = Feedback.objects.filter(quality__gt=3)
- 管家接到指令 → 去數據庫找?
quality
?字段大于 3 的所有數據,返回列表~ - 類比:你對管家說 “把展示柜里,商品質量評分大于 3 分的小泥人拿過來”,管家精準篩選后抱來~
再舉個栗子🌰
想找?“quality 不等于 5”?的數據:
obj_list = Feedback.objects.exclude(quality=5)
exclude
?是管家的 “反向篩選魔法”:排除符合條件的數據~- 類比:你對管家說 “把展示柜里,商品質量評分不等于 5 分的小泥人拿過來”,管家會過濾掉評分 5 分的,抱來剩下的~
總結(小劇場)
獲取單個數據
你:管家!把 ID=5 的小泥人拿過來~
管家:好的!(get(id=5)
?)精準找到,遞給你~
獲取全部數據
你:管家!把所有小泥人都拿過來~
管家:好的!(all()
?)抱來一整箱~
條件篩選數據
你:管家!把商品質量評分大于 3 分的小泥人拿過來~
管家:好的!(filter(quality__gt=3)
?)篩選后抱來~
四、🗑? Django ORM 刪除數據?
核心目標
教你用?Django ORM?從數據庫里?“刪除數據”?!就像給數據庫 “扔垃圾”,把不要的數據清理掉~
方法 1:實例對象刪除(精準刪單條)
# 1. 獲取要刪的數據
obj: Feedback = Feedback.objects.get(id=5) # 獲取ID=5的數據
print(f"{obj=}, {obj.text}")# 2. (可選)修改數據(這里只是示例,刪之前也能改)
obj.text = "7777"# 3. 刪除數據
obj.delete() # 刪除
1.?obj = Feedback.objects.get(id=5)
?→ 找到要刪的數據
- 管家幫你找到?“ID=5” 的那條數據?,賦值給?
obj
?~ - 類比:你對管家說 “把展示柜里 ID=5 的小泥人拿出來,我要扔了它”,管家找到后遞給你~
2.?obj.text = "7777"
?→ (可選)刪之前修改
- 刪數據前,也可以改數據(雖然改了又刪有點多余,只是演示~)
- 類比:拿到小泥人后,給它換件新衣服(改數據),但最后還是要扔~
3.?obj.delete()
?→ 把數據 “扔垃圾桶”
- 調用?
delete()
?,Django 會把?obj
?對應的數據從數據庫里?永久刪除?! - 類比:你對管家說 “把這個小泥人扔垃圾桶”,管家就把它從展示柜移除~
方法 2:類方法刪除(批量刪)
Feedback.objects.filter(text="888").delete()
1.?Feedback.objects.filter(text="888")
?→ 找到要刪的批量數據
- 管家先找到?所有 text 字段是?
"888"
?的數據?,組成一個 “待刪列表”~ - 類比:你對管家說 “把展示柜里所有衣服是?
text="888"
?樣式的小泥人找出來,我要扔了它們”,管家找到一堆小泥人~
2.?.delete()
?→ 批量扔垃圾桶
- 對 “待刪列表” 調用?
delete()
?,Django 會把這些數據?全部永久刪除?! - 類比:管家把找到的小泥人,一起扔進垃圾桶~
3. 和方法 1 的區別
- 方法 1 是?“先找到單條數據 → 刪”?,適合刪?單條數據?。
- 方法 2 是?“先篩選批量數據 → 刪”?,適合刪?多條數據?,代碼更簡潔~
總結(小劇場對比)
方法 1 小劇場
你:管家!把 ID=5 的小泥人拿過來,我要扔了它~
管家:好的!(get(id=5)
?)找到遞給你~
你:(可選:給它換件衣服)然后說 “扔了它!”(delete()
?)
管家:把小泥人從展示柜移除~
方法 2 小劇場
你:管家!把所有衣服是?text="888"
?的小泥人找出來,全部扔了~
管家:好的!(filter(text="888")
?)找到一堆小泥人,然后?delete()
?全部扔垃圾桶~
兩種方法都能刪數據,根據場景選就行啦~ 方法 1 適合刪單條,方法 2 適合批量刪!
?? 注意:刪除數據是?永久操作?,刪了就找不回來啦!一定要謹慎使用~ 🚮
(記得結合條件?filter
?精準刪數據,別不小心刪錯啦~)
五、🧙?♂? Django ORM 底層 SQL 魔法!“代碼→SQL” 的秘密?
核心目標
Django ORM 幫我們寫代碼時,底層其實是轉換成?SQL 語句?和數據庫交互的!這節課教你:
- 看 ORM 代碼對應的 SQL 長啥樣~
- 直接寫 SQL 和數據庫交互(偶爾 ORM 搞不定時用)~
顯示 SQL(看 ORM 背后的魔法咒語)
# 1. 用 ORM 寫查詢
obj_list: list[Feedback] = Feedback.objects.filter(id=5).filter(anonymous=False)# 2. 打印底層 SQL
print(f"sql={obj_list.query}")
??obj_list
?是個列表,里面裝的都是?Feedback
?數據對象~
1.?Feedback.objects.filter(...)
?→ 寫 ORM 查詢
- 你用 ORM 寫了一個查詢:找?
id=5
?且?anonymous=False
?的數據~ - 類比:你對管家說 “找 ID=5、且沒匿名的小泥人”,管家聽懂了你的需求~
2.?obj_list.query
?→ 看管家背后的 “SQL 咒語”
query
?是 ORM 查詢對象的一個屬性,存儲了?Django 轉換成的 SQL 語句?!- 打印它,就能看到:Django 到底幫你生成了什么樣的 SQL 去查數據庫~
- 類比:你好奇管家怎么和數據庫 “溝通”,于是讓管家把 “溝通咒語”(SQL)給你看~
3. 打印效果
SELECT "beifan_feedback"."id", "beifan_feedback"."quality", ...
FROM "beifan_feedback"
WHERE ("beifan_feedback"."id" = 5 AND "beifan_feedback"."anonymous" = False)
- 這就是 ORM 轉換成的 SQL 語句,數據庫會執行它來撈數據~
- 類比:管家把你的需求,翻譯成數據庫能聽懂的 “咒語”(SQL),然后執行!
執行 SQL(直接和數據庫嘮嗑)
from django.db import connectiondef my_sql():with connection.cursor() as cursor:# 1. 寫 SQL 語句cursor.execute("""SELECT *, _ROWID_ "NAVICAT_ROWID" FROM "beifan_feedback" LIMIT 0, 1000""")# 2. 獲取結果row = cursor.fetchone()return row
1.?from django.db import connection
?→ 連接數據庫
connection
?是 Django 幫我們管理的?數據庫連接對象?,負責和數據庫建立連接~- 類比:你讓管家找一個 “能直接和數據庫嘮嗑的電話”(
connection
?),用來打電話下指令~
2.?with connection.cursor() as cursor
?→ 拿 “說話的話筒”
cursor
?是 “數據庫話筒”,用它執行 SQL 語句、獲取結果~- 類比:管家拿起 “話筒”(
cursor
?),準備幫你和數據庫嘮嗑~
3.?cursor.execute(...)
?→ 說 SQL 咒語
- 你直接寫 SQL 語句,讓?
cursor
?執行~ - 這里的 SQL 是:
SELECT * FROM beifan_feedback LIMIT 0, 1000
?(查?beifan_feedback
?表,取前 1000 條 ) - 類比:你對著話筒(
cursor
?)直接說 SQL 咒語,讓數據庫執行~
4.?cursor.fetchone()
?→ 聽數據庫的回復
- 執行 SQL 后,用?
fetchone()
?獲取?第一條結果?(也可以用?fetchall()
?拿全部 )~ - 類比:你讓管家聽數據庫的回復,然后把結果拿給你~
5. 什么時候用這種方式?
- 當 ORM 搞不定復雜查詢時(比如超級復雜的多表關聯、自定義函數),可以直接寫 SQL ~
- 但要注意:直接寫 SQL 會失去 ORM 的 “跨數據庫兼容” 優勢(不同數據庫 SQL 語法可能不同)~
總結(小劇場對比)
顯示 SQL 小劇場
你:管家!我用 ORM 寫了個查詢,想看看你背后對數據庫說了啥咒語~
管家:好的!(obj_list.query
?)把 ORM 轉成的 SQL 給你看~
執行 SQL 小劇場
你:管家!我要直接和數據庫嘮嗑,說一段 SQL 咒語~
管家:好的!(connection
?+?cursor
?)幫你拿話筒、執行 SQL、拿結果~
兩種方式各有用途:
- 顯示 SQL :調試時看 ORM 有沒有按你的想法生成 SQL ,像 “查管家的小秘密”~
- 執行 SQL :ORM 搞不定時,直接寫 SQL 硬剛,像 “和數據庫直接嘮嗑”~
掌握這些,你就能看透 ORM 底層的魔法,還能手動控制 SQL 啦! 🎉