#====================================雙下劃線的跨表查詢===============
# 前提 此時 related_name=bookList
屬性查詢: # 查詢linux這本書的出版社的地址? # linux_obj=models.Book.objects.filter(title="linux").first() # print(linux_obj.publish.name) # # # 查詢老男孩出版社出版過的全部書籍的名字與價格 # # pubObj=models.Publish.objects.filter(name="老男孩出版社").first() # print(pubObj.bookList.all().values("title","price")) #此時 related_name=bookList 雙下劃線查詢 : .filter(過濾的條件) .values(要顯示的值)
注意:若是在沒有定義 related_name 時,反向查詢時 直接用表名,不須要加 _set # 查詢linux這本書的出版社的地址? --正向查詢 #ret=models.Book.objects.filter(title="linux").values("publish__addr") # print(ret) #或 --反向查詢 # ret=models.Publish.objects.filter(bookList__title="linux").values("addr") # print(ret) # 查詢老男孩出版社出版過的全部書籍的名字與價格 # ret1=models.Publish.objects.filter(name="老男孩出版社").values("bookList__title","bookList__price") # print(ret1) # # ret2=models.Book.objects.filter(publish__name="老男孩出版社").values("title","price") # print(ret2) #查詢egon出過的全部書籍的名字(多對多) ret=models.Author.objects.filter(name="egon").values("bookList__title") print(ret) ret2=models.Book.objects.filter(authorlist__name="egon").values("title") print(ret2) # egon出版過的全部書籍名稱以及出版社名稱 ret=models.Book.objects.filter(authorlist__name='egon').values('title','Publish__name') # 手機號以151開頭的做者出版過的全部書籍名稱以及出版社名稱 # 方法1: # ad=models.AuthorDetail.objects.filter(tel__startswith="151").first() # print(ad.author.bookList.all().values("title","publish__name")) # 方法2 models.Book.objects.filter(authorlist__authordetail__tel__startswith="151").values("title","publish__name")
#================================================================聚合函數 註明:下方的全部all() 均可以省略 。 不加values / values_list 獲得的就是包含對象的QuerySet,加上了就是包含字典/元組的QuerySet from django.db.models import Avg,Sum,Count,Max,Min # 聚合函數:aggregate
# 查詢全部圖書的價格和 ret=models.Book.objects.all().aggregate(priceSum=Sum("price")) print(ret) # {'priceSum': Decimal('166.00')} ret=models.Book.objects.all().aggregate(priceAvg=Avg("price"),priceSum=Sum("price"))
#單獨使用aggregate 函數聚合時,返回的是 字典 # 分組函數 annotate函數 # 查詢每一本書的做者個數 book_list=models.Book.objects.all().annotate(c=Count("authorlist__name")) #此時的book_list 是一個QuerySet for book_obj in book_list: print(book_obj.c) #按照原來得全部字段進行分組-至關於與原表同樣-,默認分紅一組, 而且分組後會在新表中新增一個 c 的字段
print(book_list) #結果:------------------------- <QuerySet [<Book: Book object>, <Book: Book object>, <Book: Book object>, <Book: Book object>, <Book: Book object>, <Boo
k: Book object>, <Book: Book object>]>
# 查詢每個出版社出版過的最便宜的書籍 ret=models.Book.objects.all().values('publish__id').annotate(Min("price")) #values內的字段就是分組字段 print(ret)
#結果:------------------------- <QuerySet [{'publish__id': 1, 'price__min': Decimal('120.00')}, {'publish__id': 2, 'price__min': Decimal('520.00')}, {'p
ublish__id': 3, 'price__min': Decimal('222.00')}]>
# 查詢每個出版社出版過的書籍個數
ret=models.Book.objects.all().values('publish__id').annotate(c=Count('name')) #values內的字段就是分組字段
print('-------------------------',ret)
#結果:------------------------- <QuerySet [{'publish__id': 1, 'c': 5}, {'publish__id': 2, 'c': 1}, {'publish__id': 3, 'c': 1}]>
分組後獲得的是一個QuerySet集合,裏面獲得的是字典形式的數據,而且只有分組依據和聚合函數的兩個字段
F 與 Q 查詢python
F查詢 在上面全部的例子中,咱們構造的過濾器都只是將字段值與某個常量作比較。若是咱們要對兩個字段的值作比較,那該怎麼作呢? Django 提供 F() 來作這樣的比較。F() 的實例能夠在查詢中引用字段,來比較同一個 model 實例中兩個不一樣字段的值。 # 查詢評論數大於收藏數的書籍 from django.db.models import F Book.objects.filter(commnetNum__gt=F('keepNum')) Django 支持 F() 對象之間以及 F() 對象和常數之間的加減乘除和取模的操做。 # 查詢評論數大於收藏數2倍的書籍 Book.objects.filter(commnetNum__gt=F('keepNum')*2) 修改操做也可使用F函數,好比將每一本書的價格提升30元: Book.objects.all().update(price=F("price")+30) Q查詢 filter() 等方法中的關鍵字參數查詢都是一塊兒進行「AND」 的。 若是你須要執行更復雜的查詢(例如OR 語句),你可使用Q 對象。 from django.db.models import Q Q(title__startswith='Py') Q 對象可使用& 和| 操做符組合起來。當一個操做符在兩個Q 對象上使用時,它產生一個新的Q 對象。 bookList=Book.objects.filter(Q(authors__name="yuan")|Q(authors__name="egon")) 等同於下面的SQL WHERE 子句: WHERE name ="yuan" OR name ="egon" 你能夠組合& 和| 操做符以及使用括號進行分組來編寫任意複雜的Q 對象。同時,Q 對象可使用~ 操做符取反,這容許組合正常的查詢和取反(NOT) 查詢: bookList=Book.objects.filter(Q(authors__name="yuan") & ~Q(publishDate__year=2017)).values_list("title") 查詢函數能夠混合使用Q 對象和關鍵字參數。全部提供給查詢函數的參數(關鍵字參數或Q 對象)都將"AND」在一塊兒。可是,若是出現Q 對象,它必須位於全部關鍵字參數的前面。例如: bookList=Book.objects.filter(Q(publishDate__year=2016) | Q(publishDate__year=2017),title__icontains="python")