django學習-15.ORM查詢方法匯總


1.前言

django的ORM框架提供的查詢數據庫表數據的方法很多,不同的方法返回的結果也不太一樣,不同方法都有各自對應的使用場景。

主要常用的查詢方法個數是13個,按照特點分為這4類:

  • 方法返回值是可迭代對象QuerySet:all(),filter(),exclude(),order_by(),reverse(),values(),values_list(),distinct();
  • 方法返回值是單個對象:get(),first(),last();
  • 方法返回值是布爾值:exists();
  • 方法返回值是數字:count();

細節:

①.學習任何一個web開發框架比如django,框架都會提供滿足90%的開發人員使用的封裝的很健壯的很多方法,每個方法都能實現相應的功能,這樣開發人員不用花大量時間去寫這些類似的方法也就避免了重復造輪子而且開發人員自己造的輪子一般健壯性不高適用場景不多。所以對於使用框架的我們而言,知道框架提供了哪些方法並知道每個方法具體怎么用的例子,我們就能很輕松地進行業務開發!

 

2.數據准備

為了結合實際例子,來驗證這13個查詢方法怎么使用,需要提前在指定的數據表里造好數據。

所以,我選擇用【hello_person】表的這三條數據當做測試數據。

 

 

3.方法返回值是可迭代對象QuerySet的每個查詢方法的如何使用的完整記錄

細節:

①.通過之前的接口調試,我們知道視圖函數【search_person】已經能被正常調用並返回我們預期的結果值。所以我們每次驗證一個查詢方法,就可以通過改造這個視圖函數【search_person】里的相關代碼邏輯來進行驗證。

 

 

3.1.查詢方法【all()】如何使用的完整記錄

細節:

①.首先,我們知道查詢一張數據表【hello_person】的所有數據的原生sql語句是:select * from hello_peroson。

②.但是,我們通過ORM框架提供的任何一個方法就都不需要寫原生sql語句,比如執行這行代碼【allData = 一張數據表對應的類名稱.objects.all()】就能返回這張表的所有數據即所有數據都存儲在這個變量【allData】里,變量【allData】是可迭代對象QuerySet,即我們要記住變量【allData】在此時是一個可迭代對象,並沒有直接給我們返回全部數據而是間接返回全部數據。如果要取出可迭代對象【allData】里的具體的數據表數據,必須要用for循環進行讀取,因為for循環就是專門用來處理列表和字典和元祖和可迭代對象的這些可被迭代的數據類型!

③.可迭代對象QuerySet的初步理解:可以把python語言里的可迭代對象QuerySet看成是java語言里的結果集,結果集可以看成是列表,結果集的作用是用於存儲每個不同的對象/不同的元祖/不同的字典。而我們也知道每個對象都是唯一的因為每個對象內存地址都是唯一的,每個類被實例化一次后就會生成對應的一個對象,我們可以通過對象去調用類里面的相關類屬性相關方法去獲取我們想要的具體的數據表表數據。

④.通過ORM框架提供的【all() 】方法的返回值是一個可迭代對象QuerySet類型數據,該類型數據類似於list。這個可迭代對象QuerySet類型數據里面每個數據都是模型類的對象。

⑤.

問題:

結果集為什么基本用來存儲從數據表獲取的數據?

大概答案:

假如一張數據表有10萬條數據,結果集里肯定有10萬個不同的對象,通過每個對象可以方便后期獲取對應的這條數據表數據的相關表字段數據。

django會對【all()】方法返回的這個可迭代對象QuerySet類型數據進行緩存,這是為了提高查詢效率。也就是說,在我們創建一個迭代對象QuerySet的時候,django並不會立即向數據庫發出查詢命令而只是獲取到對應數據里每條表數據對應的每個不同的模型類對象,只有在我們需要用到這個迭代對象QuerySet(通過for循環去調用模型類的對象)的時候才會觸發調用模型類對象里的相關方法或者相關類屬性去執行相關sql語句的查詢命令。

⑥.

問題:如何用比較接地氣的文案來描述用於存儲對象的結果集的作用?

大概答案:

比如一張數據表A里有10條數據,把一張數據表A的每條數據看成一個結果,我們就需要用每個不同的對象去裝載每個不同的結果。

就比如:一輛車裝一個人,一個對象裝一個結果。

然后現在有10個不同的人,就必須需要10輛不同的車。

可以把結果集理解為是一個很大的裝車的集裝箱,可以通過這個集裝箱裝這10輛車。

最終,我們拿到了這個集裝箱,可以通過【for循環】這個開集裝箱工具去獲取到所有的車所有的人和每個人不同的具體數據。

⑦.

問題:

比如我一張數據表A里有1萬條表數據,現在我想要獲取到這張數據表A所有表字段的具體值,有以下這兩個方案:
方案1:自己直接寫一條原生aql語句,直接返回這1萬條數據的所有表字段值的具體值。    
方案2:通過orm框架提供的一個方法all()返回有包含1萬條數據對應的對象的結果集,接着通過對象去調取相關類屬性或者方法去獲取到表字段值的具體值。
請問,我該采用哪個方案?

大概答案:
無論是基於java語言還是python語言開發的現有框架的設計都是基於ORM設計的,就是說數據自動映射對象,在業務開發過程中,任何操作也都是基於對象操作,這才符合ORM原則。
像java相關的:Mybatis, JPA, springJDBC,像python相關的:django,這些框架涉及的數據庫操作都是基於ORM。
如果我們想直接獲取表數據,一般原生的JDBC即sql語句是可以實現的,但這不是基於對象操作,不符合ORM原則。
所以說,方案1和方案2其實都可以采用,但從對象操作的角度來看,主流都是采用方案1。
 
 

3.1.1.第一步:我們可以打印出可迭代對象的值是什么。

 

 

 

 

 

3.1.2.第二步:查詢方法【all()】的具體使用。

 

 

 

 

 

細節:

①.相關源碼如下:

def search_person(request):
    '''1.通過方法all()間接獲取到hello_person表里的三個表字段id,name,age的所有數據'''
    # 第一步:新增三個數據類型為str的變量,初始值都設置為空,用於后續存儲數據;
    ids   = ''
    names = ''
    ages  = ''
    # 第二步:通過調用方法all(),返回一個數據類型為可迭代對象QuerySet的變量res;
    res = Person.objects.all()
    # 第三步:通過for循環,獲取我們想要的數據;
    for i in res:
        ids = ids + " " + str(i.id)      # 我們把表字段id的值都存儲在變量ids;
        names = names + " " + i.name     # 我們把表字段name的值都存儲在變量names;
        ages  = ages + " " + str(i.age)  # 我們把表字段age的值都存儲在變量ages;

    # 第四步:把數據返回給前端頁面;
    return HttpResponse('''
                        表字段id所有的值匯總:%s;<br/>
                        表字段name所有的值匯總:%s;<br/>
                        表字段ages所有的值匯總:%s;<br/>
                         '''%(ids,names,ages))

 

3.2.查詢方法【filter()】如何使用的完整記錄

細節:

①.首先,我們知道查詢一張數據表【hello_person】里的符合條件的數據的原生sql語句一般比如是:select * from hello_peroson where id = 9。

②.我們通過ORM框架提供的【filter()】方法也可以快速實現①的功能。

③.【filter() 】方法的返回值是一個可迭代對象QuerySet類型數據,該類型數據類似於list。這個可迭代對象QuerySet類型數據里面每個數據都是模型類的對象。

3.2.1.第一步:查詢方法【fliter()】的具體使用。

  

 

 

細節:

①.方法fiter()的傳參規則。

 

 

 

 

3.3.查詢方法【exclude()】如何使用的完整記錄

細節:

①.【exclude() 】方法的返回值也是一個可迭代對象QuerySet,返回值都是不符合查詢條件的數據。

②.【exclude() 】方法在實際開發中基本少用,基本都采用【filter()】方法。

②.【exclude() 】方法的返回值是一個可迭代對象QuerySet類型數據,該類型數據類似於list。這個可迭代對象QuerySet類型數據里面每個數據都是模型類的對象

3.3.1.第一步:查詢方法【exclude()】的具體使用。

 

 

 

 

 

 

 

3.4.查詢方法【order_by()】如何使用的完整記錄

細節:

①.【order_by() 】方法的返回值也是一個可迭代對象QuerySet,返回值都是符合排序條件的數據。

②.【order_by() 】方法的返回值是一個可迭代對象QuerySet類型數據,該類型數據類似於list。這個可迭代對象QuerySet類型數據里面每個數據都是模型類的對象。

③.入參的相關注意點:

  • 參數的字段名要加引號。
  • 如果要實現降序功能,要在字段名前面加個負號【-】。

3.4.1.第一步:查詢方法【order_by()】的具體使用。

 

 

 

3.5.查詢方法【reverse()】如何使用的完整記錄

細節:

①.【reverse() 】方法的返回值也是一個可迭代對象QuerySet,【reverse() 】方法用於對查詢結果進行反轉。

②.【reverse() 】方法在實際開發中基本少用,基本都采用【order_by()】方法。

③.【reverse() 】方法的返回值是一個可迭代對象QuerySet類型數據,該類型數據類似於list。這個可迭代對象QuerySet類型數據里面每個數據都是模型類的對象。

3.5.1.第一步:查詢方法【reverse()】的具體使用。

 

3.6.查詢方法【values()】如何使用的完整記錄

細節:

①.【values() 】方法的返回值也是一個可迭代對象QuerySet,【values() 】方法用於查詢部分字段或者全部字段的數據。

②.如果要查詢全部字段的數據,【values() 】方法的入參字段數要為0;

③.【values() 】方法的返回值是一個可迭代對象QuerySet類型數據,該類型數據類似於list這個可迭代對象QuerySet類型數據里面每個數據都不是模型類的對象而是可迭代的字典噢,字典里的鍵是表字段,值是表字段對應的數據。

3.6.1.第一步:查詢方法【values()】的具體使用。

 

 

3.7.查詢方法【values_list()】如何使用的完整記錄

細節:

①.【values_list() 】方法的返回值也是一個可迭代對象QuerySet,但【values_list() 】方法用於查詢部分字段或者全部字段的數據。

②.如果要查詢全部字段的數據,【values_list() 】方法的入參字段數要為0;

③.【values_list() 】方法的返回值是一個可迭代對象QuerySet類型數據,該類型數據類似於list這個可迭代對象QuerySet類型數據里面每個數據都不是模型類的對象而是元祖哦,元組里放的是查詢表字段對應的數據。

3.7.1.第一步:查詢方法【values_list()】的具體使用。

 

3.8.查詢方法【distinct()】如何使用的完整記錄

細節:

①.【distinct()】方法的返回值也是一個可迭代對象QuerySet。

②.【distinct()】方法的返回值是一個可迭代對象QuerySet類型數據,該類型數據類似於list。這個可迭代對象QuerySet類型數據里面每個數據都不是模型類的對象,而是每個元祖,元組里放的是查詢字段對應的數據。

③.【distinct()】方法對模型類的對象去重沒有意義,因為每個對象都是一個不一樣的存在。所以【distinct()】方法一般是跟 【values】方法 或者 【values_list】方法 一起使用,但如果跟【all()】方法一起使用是產生不了去重的效果。

④.【distinct()】方法的作用:用於對數據進行去重。

3.8.1.第一步:查詢方法【distinct()】的具體使用。

 

 

4.方法返回值是單個對象的每個查詢方法的如何使用的完整記錄

4.1.查詢方法【get()】如何使用的完整記錄

細節:

①.【get()】方法的返回值是一個模型類的對象

②.【get()】方法用於查詢符合條件的返回模型類的對象且符合條件的對象只能為一個,如果符合篩選條件的對象超過了一個或者沒有一個都會拋出錯誤。

4.1.1.第一步:查詢方法【get()】的具體使用。

 

 

 

4.2.查詢方法【first()】如何使用的完整記錄

細節:

①.【first()】方法返回符合查詢條件的結果里的第一條數據且返回的數據是模型類的對象。

4.2.1.第一步:查詢方法【first()】的具體使用。

 

 

4.3.查詢方法【last()】如何使用的完整記錄

細節:

①.【last()】方法返回符合查詢條件的結果里的最后一條數據且返回的數據是模型類的對象。

4.3.1.第一步:查詢方法【last()】的具體使用。

 

 

5.方法返回值是布爾值的每個查詢方法的如何使用的完整記錄

5.1.查詢方法【exists()】如何使用的完整記錄

細節:

①.【exists()】方法用於判斷查詢的結果 QuerySet 列表里是否有數據。

②.【exists()】方法返回值的數據類型是布爾值,有數據則返回值為true,沒有數據則返回值為false。

 

5.1.1.第一步:查詢方法【get()】的具體使用。

 

 

6.方法返回值是數字的每個查詢方法的如何使用的完整記錄

6.1.查詢方法【count()】如何使用的完整記錄

細節:

①.【count()】方法用於查詢數據的數量且返回的數據是整數。 

6.1.1.第一步:查詢方法【count()】的具體使用。

 

 

 

7.相關的學習資料地址

①.django的ORM框架提供的查詢數據庫表數據的所有方法具體使用,可以查看該菜鳥教程地址:https://www.runoob.com/django/django-orm-1.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM