1. 程式人生 > >ORM查詢之基於物件的正向查詢與反向查詢

ORM查詢之基於物件的正向查詢與反向查詢

 一、為什麼有正向查詢和反向查詢?

舉例有兩張表,一張表叫書籍表,一張表叫出版社表,他們關係是一對多的關係,書籍是一,出版社是多,因為一本書應該只有一個出版社對應,而出版社可以有多本書對應。

那麼在實際程式碼中定義他們關係的類中,設定外來鍵的那個屬性"publisher"是在多的那個類中,也就是在書籍這個類中,所以在書籍類中,想要知道某一本書對應的出版社,就可以通過例項化一個物件,然後通過他的屬性publisher又例項化一個出版社的物件,拿到對應的出版社,這個按照python的解釋來說,就是正常的通過一個例項化物件,取某一個屬性,很正常,邏輯順序明瞭,被稱之為正向查詢;但是在出版社表中,對應的類中,它只有與自己屬性相關的定義啊,比如出版社名字,地址等等,它沒有屬性是來確定和書籍這個表有關係的,所以,想取某一個出版社對應的有哪些書,用例項化一個物件來操作,行不通,這時這種情況就是反向查詢了。

 

兩種查詢具體怎麼操作,如下:

給出兩個表對應的類定義和生成的資料表:

 

書籍類:

生成的對應資料表:

 

 

 出版社類:

生成的對應資料表:

 

 


 

 

 正向查詢

 現在通過正向查詢,也就是要查詢某本書對應的是哪一個出版社。從上面的表中,我們看到,書籍是有重複的,但是出版社是一樣的,那麼查詢ID=2的那本書對應的出版社。

 1 from orm測試.models import Book           #匯入Book模組
2 3 b=Book.objects.filter(id=2)[0] 4 #當後面不加[0]時,拿到的是一個QuerySet集合,加上就是一個物件,只有物件才能取值。 5 6 7 8 chubanshe=b.publisher.name 9 #b已經是書籍的一個物件,b.publisher又是一個物件,這個物件就是出版社的物件,因為#publisher是Book類中的一個外來鍵。b.publisher.name就拿到了對應的出版社名字。 10 11 print(chubanshe)

來看看上面程式碼每一步拿到的都是些什麼。

程式碼:b=Book.objects.filter(id=2)拿到的是什麼(不加[0])?如圖:

b拿到的是一個QuerySet集合,型別是django型別的類(這個是什麼具體還不清楚),但是這個肯定不是我想要的物件。

 

 

程式碼:b=Book.objects.filter(id=2)[0]拿到的是什麼?如圖:

b輸出是一個具體的值?但是實際上並不是,列印它的型別一看就知道,它其實是一個類例項化的一個物件,也就是想要查詢id=2這本書叫“三國演義”的物件。

 

 

程式碼:chubanshe=b.publisher.name拿到的是什麼?

分開來看這句程式碼,先看chubanshe=b.publisher是什麼?先把b.publisher的值賦給了chubanshe,方便輸出檢視。

首先publisher是Book類的一個屬性,同時也是一個外來鍵,很明顯b.publisher是在拿屬性的值。看看它拿到的是什麼?如圖:

看到,結果是跟上面一樣,也是一個具體的值,其實就是出版社的一個例項化的一個物件。好了,到這裡明白了,既然出版社的一個例項化的物件有了,那麼取裡面屬性的值就很好辦了。

程式碼chubanshe=b.publisher.name拿到的自然就是從一開始想要得到那本書本的對應的出版社的名字:

結果就是想要的,對應的出版社,查表可以確定結果只正確的,並且這個值的型別是字串型別,一個真正的值。

 

 

 反向查詢

 現在通過反向查詢,也就是要查詢某個出版社對應哪些書。那麼查詢ID=2這個出版社有哪些書。

既然是反向,出發點一定是從表出版社出發,查到表書籍。

1 1 from orm測試.models  import Publish
2 2 
3 3 p=Publish.objects.filter(id=2)[0]         #這裡跟正向查詢一樣,拿到一個物件
4 4 
5 5 ret=p.book_set.values("title").distinct()    #取出版社對應的所有書
6 6 
7 7 print(ret)

這裡主要分析程式碼ret=p.book_set.values("title").distinct()

book_set是反向查詢的一個方法,book對應的就是要到Book表裡面,_set就是拿到了要查詢的所有書籍,distinct()是去重。

結果如圖: