官網:https://doc.cfd.direct/openfoam/user-guide-v9/platehole $FOAM_TUTORIALS/stressAnalysis/solidDisplacementFoam下的案例 1、網格劃分 /* *- C++ -* *\ | \\ / F ie ...
本篇筆記為Django筆記系列之十二,首發於公號【Django筆記】
本篇筆記將介紹查詢中的 defer 和 only 兩個函數的用法,筆記目錄如下:
- defer
- only
1、defer
defer 的英語單詞的意思是 延遲、推遲,我們可以通過將欄位作為參數傳入,可以達到在獲取數據的時候指定不獲取該欄位數據,常用於一些 textfield 欄位上。
假設我們有一個 TestModel,有一個欄位名為 text_field,欄位類型為 textfield,裡面存了大量字元串數據.
那麼如果我們在獲取這個 model 數據的時候,只想要這個 model 的其他欄位信息, text_field 欄位的內容我們在這一次用不上,那麼我們就可以通過 defer() 方法來指定不獲取該欄位內容。
因為對於這一類大容量數據,系統在從資料庫中 fetch 數據的時候會花費大量時間,而這部分不必要的時間我們是可以避免的。
TestModel.objects.defer("text_field")
上面的語句將 text_field 這個欄位名作為參數傳入 defer() 函數,系統返回數據的時候將不會返回他的欄位。
我們以 Blog 這個model為例對這個函數進行測試,我們獲取 Blog 的數據,但是指定不獲取 name 這個欄位的數據:
Blog.objects.defer("name")
我們可以列印一下這條命令執行的 SQL 語句:
Blog.objects.defer("name").query.__str__()
SELECT `blog_blog`.`id`, `blog_blog`.`tagline` FROM `blog_blog`
可以看到轉化的 SQL 語句沒有把我們指定的 name 欄位返回。
不獲取外鍵關聯的某些欄位
如果我們通過 select_related 關聯了外鍵數據,也可以指定不獲取外鍵的某些欄位,比如:
Entry.objects.select_related("blog").defer("blog__name")
這樣,在獲取關聯的 blog 的數據的時候,就不會獲取 blog 的 name 欄位數據。
defer 多欄位
Entry.objects.defer('headline', 'body_text')
主鍵欄位不能defer
有一些欄位我們是 defer 也不會生效的,比如 model 的主鍵欄位 id。
Blog.objects.defer("id")
上面的操作,系統不會報錯,但是也不會生效。
關聯外鍵數據,外鍵數據不應該被 defer
假設我們通過 Entry 來關聯獲取 Blog 數據,那麼,關聯的外鍵欄位 blog_id,則不應該被 defer(),否則會報錯。
# 下麵的寫法會報錯
Entry.objects.select_related("blog").defer("blog_id")
訪問被 defer 的欄位
假設我們在獲取 Blog 數據的時候,defer 了 name 欄位,那麼我們還可以訪問 name 欄位嗎?
答案是可以的,不過因為我們在第一步的時候沒有獲取該欄位,所以訪問該欄位的時候,系統會再次請求一遍資料庫。
blog = Blog.objects.defer("name").first()
"""
這個時候列印出 blog 的所有欄位是:
blog.__dict__
{'_state': <django.db.models.base.ModelState object at 0x7fb2de420668>, 'id': 1, 'tagline': 'asd'}
"""
print(blog.name) # 訪問被 defer 的欄位,系統會再次請求資料庫
"""
這個時候再次列印出 blog.__dict__ 內容是:
{'_state': <django.db.models.base.ModelState object at 0x7fb2de420668>, 'id': 1, 'tagline': 'asd', 'name': 'hunter'}
"""
2、only
與 defer() 方法的作用相反,only() 的意思是只獲取指定的欄位,比如:
Entry.objects.only("headline", "rating")
與之對應的 SQL 是:
SELECT `blog_entry`.`id`, `blog_entry`.`headline`, `blog_entry`.`rating` FROM `blog_entry`
同樣的,如果訪問沒有指定的欄位,系統會再次查詢資料庫。
如果是多個 only 連用,那麼系統只有最後一個 only 的欄位會生效:
Entry.objects.only("headline", "rating").only("body_text") # 只會獲取 body_text 欄位數據
作用效果跟 order_by() 一樣,後面的參數會覆蓋前面的。
defer 和 only 連用
我們可以嘗試一下 defer 和 only 的先後順序,欄位是否相同,前者的欄位覆蓋後者,以及後者的欄位覆蓋前者等情況,這裡不做展開了。
因為,一般人誰會把這個兩個函數一起用呢。。。。。。
以上就是本篇筆記所有內容,下一篇筆記將介紹 get_or_create,update_or_create 等方法。
本文首發於本人微信公眾號:Django筆記。
原文鏈接:Django筆記十二之defer、only指定返回欄位
如果想獲取更多相關文章,可掃碼關註閱讀: