Django筆記十三之select_for_update等選擇和更新等相關操作

来源:https://www.cnblogs.com/hunterxiong/archive/2023/04/01/17279676.html
-Advertisement-
Play Games

無論對於什麼業務來說,用戶數據信息的安全性無疑都是非常重要的。尤其是在數字經濟大火背景下,數據的安全性就顯得更加重要。數據脫敏可以分為兩個部分,一個是DB層面,防止DB數據泄露,暴露用戶信息;一個是介面層面,有些UI展示需要數據脫敏,防止用戶信息被人刷走了。 v需求背景 DB層面的脫敏今天先不講,今 ...


本篇筆記將介紹 update 和 create 的一些其他用法,目錄如下:

  1. get_or_create
  2. update_or_create
  3. select_for_update
  4. bulk_create
  5. bulk_update

1、get_or_create

前面我們介紹過 get() 和 create() 的用法,那麼 get_or_create() 的意思很簡單,就是 獲取或者創建,如果存在就返回,不存在就先創建再返回

假設對於 Blog model,我們想看下資料庫有沒有 name="hunter", tagline="tagline_test" 的數據,沒有的話創建並獲取這條數據,有的話,就直接獲取。

在之前我們操作可能是:

try:
	blog = Blog.objects.get(name='hunter', tagline='tagline_test')
except Blog.DoesNotExist:
	blog = Blog(name='hunter', tagline='tagline_test')
	blog.save()		

現在我們可以直接這樣操作:

blog, created = Blog.objects.get_or_create(name='hunter', tagline='tagline_test')

這個函數的返回值有兩個,一個是操作的 model 實例,一個是是否是 created 的 布爾型數據。

created 為 True,表示這條數據是創建,create() 到的
created 為 False,表示這條數據是獲取, get() 到的

註意: 查詢的條件必須是唯一的,否則會造成多條數據返回而報錯,這個邏輯同 get() 函數。

註意: 使用的欄位,沒有唯一的約束,併發的調用這個方法可能會導致多條相同的值插入。

欄位預設值

假設 Blog 這個 model 除了 name, tagline 這兩個欄位外,還有 field_1 和 field_2 欄位,但是他們不在我們查詢的條件內,作用為在創建的時候設置的預設值,我們可以通過 defaults 來操作:

blog, created = Blog.objects.get_or_create(
	name='hunter', 
	tagline='tagline_test',
	defaults={
		'field_1': 'field_1_value',
		'field_2': 'field_2_value'
	}
)

最後關於這個函數,有個小提示,如果這個函數用在介面里,那麼根據冪等性,我們應該使用 POST 方法來請求,而不是 GET 請求。

關於冪等性的概念,有興趣的話可以去查詢一下。

2、update_or_create

更新或者創建,使用方法同 get_or_create()

假設對於 Blog model 我們想實現的操作如果存在 name='hunter', tagline='tagline_test' 的數據就將其 field_1 和 field_2 的欄位更新,不存在的話,就創建該數據。

之前的操作邏輯大概如下:

defaults = {"field_1": "field_1_value", "field_2": "field_2_value"}

try:
	obj = Blog.objects.get(name='hunter', tagline='tagline_test')
	for key, value in defaults.items():
		setattr(obj, key, value)
	obj.save()
except:
	new_values = {"name": "hunter", "tagline": "tagline_test}
	new_values.update(defaults)
	obj = Blog(**new_values)
	obj.save()

現在我們使用 update_or_create 可以如下操作:

obj, created = Blog.objects.update_or_create(
	name='hunter', tagline='tagline_test',
	defaults={"field_1": "field_1_value", "field_2": "field_2_value"}
)

3、select_for_update

select_for_update 的操作複雜一點,作用類似於 SQL 中的 SELECT ... FOR UPDATE 語句

操作如下:

from django.db import transaction

blog_list = Blog.objects.select_for_update().filter(name="hunter")
with transaction.atomic():
	for blog in blog_list:
		...

當 blog_list 去獲取數據的時候,所有匹配上的 entries 都會被鎖,直到這個事務結束。

意味著這個時候,其他的事務會被阻止更改或者重新在這些數據上加鎖。

我們來舉個例子,在我們執行下麵的語句時:

import time
from django.db import transaction

blog_list = Blog.objects.select_for_update().filter(name="hunter")
with transaction.atomic():
	for blog in blog_list:
		print("locking ...")
		time.sleep(20)

這個時候,我們在重新開一個 shell,來執行下麵的語句:

Blog.objects.filter(name="hunter").update(name="hunter_1")

因為第一個 shell 里執行的命令還沒有結束,而且在數據上加了鎖,因此第二個 shell 里的語句會進入等待,直到第一個 shell 里的命令執行完成之後,第二個 shell 里的命令才會執行。

註意: 如果在第一個命令里,對 blog 數據進行操作,比如 把 name 欄位改為了 hunter_2,那麼在第二條命令的條件里篩選不到結果然後更新的。

4、bulk_create

批量創建,在前面介紹增刪改查的時候介紹過一次,這裡再簡單做一下示例:

from blog.models import Blog

blog_list = [
	Blog(name="hunter_1", tagline="tag_1"),
	Blog(name="hunter_2", tagline="tag_2"),
	Blog(name="hunter_3", tagline="tag_3"),
	Blog(name="hunter_4", tagline="tag_4")
]

Blog.objects.bulk_create(blog_list)

如果我們批量創建的數量過多,我們可以指定分批次來創建,通過 batch_size 參數來指定。

Blog.objects.bulk_create(blog_list, batch_size=2)

5、bulk_update

批量更新,方式與 bulk_create 的方式類似,以下是使用示例:

blog_list = Blog.objects.filter(id__lte=20)

for blog in blog_list:
	blog.name = "name_updated"
	blog.tagline = "tag_updated"

Blog.objects.bulk_update(blog_list, fields=['name'], batch_size=2)

需要註意的是 bulk_update 多了個參數,fields 這個是用來指定需要更新的欄位。

如我們上面的命令所示,我們指定更新的是 name 欄位,那麼就算我們更改了 tagline 的數據,只要 fields 列表裡沒有指定該欄位,那麼後臺也不會更新該欄位。

以上就是本篇筆記全部內容,接下來我們將介紹一下查詢中的其他用法,比如latest,first,contains 等。

本文首發於本人微信公眾號:Hunter後端

原文鏈接:Django筆記十三之select_for_update等選擇和更新等相關操作

如果想獲取更多相關文章,可掃碼關註閱讀:
image


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 包含五個內容:①Navicat連接伺服器MySQL;②如何查看MySQL用戶名和密碼;③修改MySQL登錄密碼;④error 1045 (28000): access denied for user 'root'@'localhost' (using password:yes)錯誤解決方法;⑤安裝M... ...
  • 一:在hadoop3.3中安裝配置sqoop1.4.7 前言: sqoop功能已經非常完善了,沒有什麼可以更新的了,官方停止更新維護了。因此官方集成的hadoop包停留在了2.6.0版本,在hadoop3.3.0版本會提示類版本過低錯誤,但純凈版sqoop有缺少必須的第三方庫,所以將這兩個包下載下來 ...
  • 1. 集合論是SQL語言的根基 1.1. UNION 1.1.1. SQL-86標準 1.2. NTERSECT和EXCEPT 1.2.1. SQL-92標準 1.3. 除法運算(DIVIDE BY) 1.3.1. 沒有被標準化 2. 註意事項 2.1. SQL能操作具有重覆行的集合,可以通過可選項 ...
  • 說明 有讀者反饋: 學習uniapp ios 插件開發不知道從哪些文章看起,沒有一個清晰的學習路線 本文就做一個解答。 首先本系列的文章是作者精心排過序的,如果想要完整的學習uniapp ios原生插件開發技術的話,建議是按文章順序瀏覽。 當然您如果有相關的開發經驗,且只對某一技術實現感興趣的話,也 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 最近碰到這樣一個問題,在一張封面上直接顯示書名,可能會存在書名看不太清楚的情況(容易受到背景干擾),如下 為瞭解決這個問題,設計師提了一個“究極”方案,將書名背後的圖片模糊一下,這個在 CSS 中很好實現,僅需backdrop-filte ...
  • 路由守衛 作用:對路由進行許可權控制 配置路由守衛應在暴露前配置 分類:全局守衛、獨享守衛、組件內守衛 首先先給需要鑒權的路由設置好meta配置項。 meta配置項:是vue-router中的一個對象,主要用於存儲路由的元數據(meta data)信息。這些元數據信息可以是一些描述性的內容,比如頁面的 ...
  • 泛型、Trait、生命周期 一、提取函數消除重覆 fn main() { let number_list = vec![34, 50, 25, 100, 65]; let mut largest = number_list[0]; for number in number_list { if num ...
  • Spring是什麼? Spring是一個輕量級的控制反轉(IoC)和麵向切麵(AOP)的容器框架。 Spring的優點 通過控制反轉和依賴註入實現松耦合。 支持面向切麵的編程,並且把應用業務邏輯和系統服務分開。 通過切麵和模板減少樣板式代碼。 聲明式事務的支持。可以從單調繁冗的事務管理代碼中解脫出來 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...