一、為什麼有正向查詢和反向查詢? 舉例有兩張表,一張表叫書籍表,一張表叫出版社表,他們關係是一對多的關係,書籍是一,出版社是多,因為一本書應該只有一個出版社對應,而出版社可以有多本書對應。 那麼在實際代碼中定義他們關係的類中,設置外鍵的那個屬性"publisher"是在多的那個類中,也就是在書籍這個 ...
一、為什麼有正向查詢和反向查詢?
舉例有兩張表,一張表叫書籍表,一張表叫出版社表,他們關係是一對多的關係,書籍是一,出版社是多,因為一本書應該只有一個出版社對應,而出版社可以有多本書對應。
那麼在實際代碼中定義他們關係的類中,設置外鍵的那個屬性"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()是去重。
結果如圖: