『Django ORM』完整總結

因爲官方文檔通常講究『平均發力,面面俱到』,雖然內容是詳細,可是對於初學者每每是『不知輕重,找不着北』。本文試圖總結一些 Django ORM 中比較經常使用的東西,力求覆蓋全面,實現『花20%的時間,搞定80%的內容』的目的。python

【ORM class 的定義】

這個很是簡單,基本無腦使用。注意,這裏我假設:使用者基本不使用『物理層外鍵』,外鍵邏輯再應用層控制(這個話題見仁見智,各有各的選擇)。數據庫

【建立】

有二者風格,一種是:django

# 一開始就直接把屬性所有列舉出來, 並建立對象
blog_orm = Blog(title="xxx", name="xxx", ...)
blog_orm.save()
複製代碼

另外一種是:bash

# 先將對象建立出來,雖然再根據要求(條件),填充對應的屬性。
blog_orm = Blog()
blog_orm.title = "xxx"
if some_condition:
    blog_orm.name = "yyy"

blog_orm.save()
複製代碼

兩種方式沒有優劣,可是第二種更加常見,由於通常數據庫表有許多字段,建立ORM對象時,那個時間點的上下文,是並不能獲取到某些屬性,這些屬性多是後續根據某些條件生成的,或者依賴一些特定的參數。學習

【查詢】

Django ORM的查詢,基本上算是一門小的 DSL 了,並且只適用於 Django ORM,並不能遷移到其餘領域,對於我的而言,這種東西,屬於價值比較有限的東西,花太多力氣學習是不值得的。相比之下,多發點時間瞭解 SQL ,可能更加有價值,由於它的適用範圍更加普遍。ui

  1. 記住幾個個API。Django ORM的 API很是統一,這是比較好的消息。
.filter(**kw)           正面條件,好比 等於/大於
.exclude(**kw)          方面條件,好比 不能於/不是
Q(**kw)                 OR 邏輯,好比條件1 或者 條件2,使用形式爲: Q(name="xxx") | Q(sex="yyy"複製代碼
  1. 風格分爲兩種。
第一種:求出QuerySet。
這是最經常使用,也最實用的, 由於QuerySet 有很是完備系統的API,後文詳述之。若是沒有特殊狀況,通常使用這種方式
好比:user_qs = User.objects.filter(name="xxx").filter(sex="yyy").exclude(age=22)

第二種:直接求值出來,即 .first() .all()這些方法
這種通常只在特定並且肯定的狀況下,纔去使用,範圍比較受限
好比:
    user_qs = 
    one_user_obj = user_qs.first()
    all_user_objs = user_qs.all()
複製代碼
  1. 並不須要特別記憶的『Lookup Expression』
無非是映射到SQL的WHERE中的條件而已,用幾回就熟悉了。
Django文檔,有個專門的連接講這個東西,即使如此,經常使用的也就那麼幾個。
複製代碼
  1. LIMIT OFFSET
這個須要特別發點時間去記憶。
一直不明白,Django 爲何不提供 .offset() .limit() 這樣的 API,而是搞成『很照顧Python習慣』的切片方式,
這樣,雖然照顧了『Python的習慣』,可是使用中不免有點心智上的負擔,由於他的大腦須要自動映射到SQL的 OFFSET/LIMIT,

一直以爲,ORM不該該搞太厚的邏輯,也不要夾帶太多私貨,一切應該以『照顧SQL的習慣』爲基準。
複製代碼

【修改】

  1. 單個修改
這個很是簡單易用
user_obj.name = "new_name"
user_obj.save()
複製代碼
  1. 批量修改
對符合某一組查詢條件的ORM對象列表,進行批量更新
user_qs = 
user_qs.udpate(name="new_name")
複製代碼

【刪除】

  1. 單個刪除:user_obj.delete()
  2. 批量刪除
user_qs = 
user_qs.delete()
複製代碼

【事務】

這個絕對是很是重要的,不是由於再Django中這個東西重要,而是由於這個東西自己就重要,跟Django不Django沒有半點關係。atom

再Django中使用,很是簡單:spa

from django.db import transaction
with transaction.atomic():
    do_more_stuff()
複製代碼
相關文章
相關標籤/搜索