Django中g(shù)et()與filter()的區(qū)別及常見錯誤
在 Django 中,get() 和 filter() 是 QuerySet API 中用于檢索數(shù)據(jù)的兩個核心方法,它們的功能和使用場景有明顯區(qū)別。以下是詳細(xì)對比:
1. 核心區(qū)別
| 特性 | get() | filter() |
|---|---|---|
| 返回值 | 單個對象(模型實例) | 查詢集(QuerySet,可迭代) |
| 數(shù)量限制 | 必須精確匹配1個對象 | 可以匹配0個、1個或多個對象 |
| 對象不存在時 | 拋出 DoesNotExist 異常 | 返回空查詢集(不報錯) |
| 多對象匹配時 | 拋出 MultipleObjectsReturned 異常 | 返回包含多個對象的查詢集 |
| 鏈?zhǔn)秸{(diào)用 | 不支持(返回的是模型實例) | 支持(可繼續(xù)添加過濾條件) |
2. 語法與示例
get()的用法
# 獲取 ID 為 1 的書(必須存在且唯一)
book = Book.objects.get(id=1)
# 等價的手動異常處理
try:
book = Book.objects.get(id=1)
except Book.DoesNotExist:
# 處理不存在的情況
pass
except Book.MultipleObjectsReturned:
# 處理多對象匹配的情況
pass
filter()的用法
# 獲取所有已發(fā)布的書(可能有0本或多本) books = Book.objects.filter(status='published') # 鏈?zhǔn)竭^濾:獲取已發(fā)布且價格大于 50 的書 books = Book.objects.filter(status='published').filter(price__gt=50) # 等價的單語句寫法 books = Book.objects.filter(status='published', price__gt=50) # 獲取第一本書或 None(推薦替代 get() 的安全寫法) first_book = books.first() # 等價于 books[0] if books else None
3. 性能對比
get():直接查詢單條記錄,生成的 SQL 類似SELECT ... WHERE ... LIMIT 1,理論上更高效。filter().first():生成的 SQL 是SELECT ... WHERE ... LIMIT 1,與get()幾乎相同,但多了一步 Python 對象轉(zhuǎn)換,性能損耗可忽略不計。
注意:在查詢條件唯一(如主鍵查詢)時,兩者性能接近;但 filter().first() 更安全。
4. 適用場景
推薦使用get()的場景
- 查詢條件唯一(如通過主鍵或唯一鍵查詢)。
- 對象必須存在,否則視為程序錯誤(如配置項、固定ID的系統(tǒng)數(shù)據(jù))。
- 示例:
user = User.objects.get(username='admin') # 管理員用戶必須存在
推薦使用filter()的場景
- 查詢條件不唯一(如按類別篩選商品)。
- 結(jié)果可能為空(如搜索功能)。
- 需要鏈?zhǔn)讲樵?/strong>(如分頁、排序、多條件組合)。
- 示例:
# 搜索功能(結(jié)果可能為空) books = Book.objects.filter(title__icontains='python') # 分頁查詢 books = Book.objects.filter(category='tech').order_by('-pub_date')[:10]
5. 常見錯誤案例
錯誤使用get()的場景
# 錯誤:title 可能不唯一,導(dǎo)致 MultipleObjectsReturned book = Book.objects.get(title="Python") # 正確:使用 filter().first() book = Book.objects.filter(title="Python").first()
低效的filter()使用
# 低效:兩次數(shù)據(jù)庫查詢
if Book.objects.filter(id=1).exists():
book = Book.objects.get(id=1) # 重復(fù)查詢
# 高效:單次查詢
book = Book.objects.filter(id=1).first()
6. 總結(jié)
| 場景 | 方法 |
|---|---|
| 通過主鍵/唯一鍵獲取單個對象 | get()(需確保存在) |
| 安全獲取單個對象(不存在時返回 None) | filter().first() |
| 查詢可能存在多個結(jié)果或空結(jié)果 | filter() |
| 需要鏈?zhǔn)讲樵儯ㄈ绶猪?、排序?/td> | filter() |
建議:優(yōu)先使用 filter().first() 替代 get(),除非你能絕對保證查詢條件的唯一性和存在性。
到此這篇關(guān)于Django中g(shù)et()與filter()的區(qū)別及常見錯誤的文章就介紹到這了,更多相關(guān)Django中g(shù)et()與filter()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python 設(shè)置xlabel,ylabel 坐標(biāo)軸字體大小,字體類型
這篇文章主要介紹了python 設(shè)置xlabel,ylabel 坐標(biāo)軸字體大小,字體類型,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
Python selenium爬蟲實現(xiàn)定時任務(wù)過程解析
這篇文章主要介紹了Python selenium爬蟲實現(xiàn)定時任務(wù)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-06-06
Django 拼接兩個queryset 或是兩個不可以相加的對象實例
這篇文章主要介紹了Django 拼接兩個queryset 或是兩個不可以相加的對象實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03
python畫圖——實現(xiàn)在圖上標(biāo)注上具體數(shù)值的方法
今天小編就為大家分享一篇python畫圖——實現(xiàn)在圖上標(biāo)注上具體數(shù)值的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-07-07
安裝ElasticSearch搜索工具并配置Python驅(qū)動的方法
這篇文章主要介紹了安裝ElasticSearch搜索工具并配置Python驅(qū)動的方法,文中還介紹了其與Kibana數(shù)據(jù)顯示客戶端的配合使用,需要的朋友可以參考下2015-12-12

