一篇文章帶你了解Django ORM操作(進階篇)
回顧
上次咱們學習了一下Django ORM的基本查詢操作。
查詢操作主要使用的是filter()方法。
我們知道filter()查詢出來的是值,如果想取第一個值需要再filter().first()才行。
還知道了get()和filter().first()的區別等等。
Django ORM的查詢還有很多,繼續來看叭!!!
查詢操作
對象.外鍵字段
比如,我們拿到了一個書的信息,我們可以這樣打印他的信息。
代碼
- book = models.Book.objects.filter(title="<<大明帝國>>").first()
- print(f"book類型:{type(book)}")
- print(f"id:{book.id}")
- print(f"書名:{book.title}")
- print(f"價格:{book.price}")
- print(f"書名:{book.PublishDate}")
- print(f"出版社:{book.publish}") # 外鍵字段
執行結果
注:藍色為外鍵字段
不知道你有沒有疑問,為什么book.publish會把郵電出版社打印出來。
這個原因主要在于外鍵對象的__str__方法。
就是因為我Publish返回的是self.title,所以才能打印出來郵電出版社,如果我想打印出版社聯系方式咋辦?
代碼
- print(f"出版社類型:{type(book.publish)}") # <class 'web.models.Publish'>
- # book.publish已經是models.Publish對象,所以可以自由調里面的屬性
- print(f"出版社電話:{book.publish.phone},")
執行結果
總結
對象.外鍵字段拿到的就是外鍵字段對象,直接就可以通過對象.外鍵字段.外鍵屬性獲取具體值。
反向查詢(表名__set.all())
上述我們是通過正向查詢的方式查詢到了書對應的出版社具體信息。
但是如果說,我們拿到的就是一個出版社名呢?
通常情況下,你可能會這樣!
代碼
- # 查詢郵電出版社
- publish_obj = models.Publish.objects.filter(title="郵電出版社").first()
- # 獲取出版社id
- publish_id = publish_obj.id
- # 查詢publish_id為出版社id的
- book_list = models.Book.objects.filter(publish_id=publish_id)
- print(book_list)
執行結果
其實,還有一種方法:通過一個對象,反向查多個對象。
代碼
- publish_obj = models.Publish.objects.filter(title="郵電出版社").first()
- book_list = publish_obj.book_set.all()
- print(book_list)
執行結果
雙下劃線跨表查詢
還是上述這個問題,通過一個出版社名,查找屬于這個出版社的圖書。
基于雙下劃線的跨表查詢,理論是更簡單的!
注:可以看到還有__contains等其他filter條件查詢,通過__跨表依然是可以通用的。
代碼
- book_list = models.Book.objects.filter(publish__title="郵電出版社")
- print(book_list)
執行結果
連續跨表
__不僅可以進行跨一張表,還能跨多張表。
以圖書Many作者表為例,根據出版社查詢圖書和作者多對多的信息。
代碼
- ret = models.BookManyAuthor.objects.filter(book__publish__title="郵電出版社")
- print(ret)
跨了book表又跨了publish表
執行結果
values
有時候,我們可能只需要一些特定的列,這時候使用values即可。
代碼
- # 語法
- book_list = models.Book.objects.all().values("列1","列2",...)
- # 示例
- book_list = models.Book.objects.all().values("title","price")
- print(book_list)
代碼
values返回的值有點像列表套字典,但是其實本質還是QuerySet類型。
values_list
values_list和values功能一樣,都是取相關的列,但是返回的類型格式不一樣。
代碼
- book_list = models.Book.objects.all().values_list("title","price")
- print(book_list)
執行結果
這個有點像列表套元組,但是其實本質還是QuerySet。
related_name
related_name通常用于反向查詢時,替換<表名>_set。
原方式
models.py
代碼
- # 查詢郵電出版社
- publish = models.Publish.objects.filter(title="郵電出版社").first()
- print(publish)
- # 反向一對多
- book_list = publish.book_set.all()
- print(book_list)
執行結果
別名方式
models.py
代碼
- # 查詢郵電出版社
- publish = models.Publish.objects.filter(title="郵電出版社").first()
- print(publish)
- # 反向一對多
- book_list = publish.book_list.all()
- print(book_list)
執行結果
filter().filter()...
上文我們說過,是支持多個filter的,filter(<條件>).filter(<條件>)...
這種情況通常用于不確定篩選條件,但是多層篩選的情況下。
代碼
- # 舉例而已,后面filter里面可以是其他 或 的條件
- book1 = models.Book.objects.filter(title="<<大明帝國>>").filter(price="99")
- # 效果同上
- book2 = models.Book.objects.filter(title="<<大明帝國>>",price="99")
- print(book1)
- print(book2)
執行結果
總結
本篇主要還是上篇的繼續補充,還是關于filter的查詢部分。
本次主要有外鍵字段類型,反向查詢默認使用<表名>__set,還可以使用related_name反向字段查詢。
雙下劃線可以進行條件查詢,還可以進行跨表查詢,還可以連續跨表,values和values_list區別。
多個filter進行條件篩選。
如果在操作過程中有任何問題,記得下面留言,我們看到會第一時間解決問題。
用微笑告訴別人,今天的我比昨天強,今后也一樣。
本文轉載自微信公眾號「Python爬蟲與數據挖掘」,可以通過以下二維碼關注。轉載本文請聯系Python爬蟲與數據挖掘公眾號。