Django 聚合查詢及使用步驟
一、聚合查詢
使用聚合查詢前要先從 django.db.models 引入 Avg、Max、Min、Count、Sum(首字母大寫)
聚合查詢返回值的數(shù)據(jù)類型是字典
聚合查詢使用aggregate()
對(duì)查詢集執(zhí)行聚合操作,它允許我們使用數(shù)據(jù)庫提供的聚合函數(shù)(如 COUNT(), AVG(), SUM(), MAX(), MIN() 等)來對(duì)查詢集中的數(shù)據(jù)進(jìn)行匯總計(jì)算,aggregate()
方法返回一個(gè)字典,字典的鍵是你指定的聚合函數(shù)別名,值是聚合計(jì)算的結(jié)果
queryset.aggregate(聚合函數(shù)) # 別名使用 queryset.aggregate(別名 = 聚合函數(shù)名("屬性名稱")) # 例: result = Book.objects.aggregate(average_price=Avg('price'), total_books=Count('id')) # 結(jié)果示例: {'average_price': 100.25, 'total_books': 150}
二、使用步驟
1.準(zhǔn)備工作
還是之前那個(gè)fa的項(xiàng)目目錄,在views.py內(nèi)引入
# 導(dǎo)入聚合函數(shù) from django.db.models import Avg,Max,Min,Count,Sum
在models.py里面,定義一個(gè)Book模型
class Book(models.Model): title = models.CharField(max_length=255) # 書名 author = models.CharField(max_length=255) # 作者 price = models.DecimalField(max_digits=10, decimal_places=2) # 價(jià)格 rating = models.FloatField() # 評(píng)分 published_date = models.DateField() # 出版日期 pages = models.IntegerField() # 頁數(shù) def __str__(self): return self.title
在數(shù)據(jù)庫生成book表,執(zhí)行下列命令
python manage.py makemigrations python manage.py migrate
這個(gè)時(shí)候我們就有一張book的表了,我們自己手動(dòng)塞入一些數(shù)據(jù)(這里就不做新增了),然后在下一步實(shí)現(xiàn)聚合函數(shù)的使用
隨意添加的數(shù)據(jù)
2.具體使用
定義一個(gè)方法去使用聚合函數(shù),我們?cè)趘iews.py里面添加一個(gè)方法
def getBookSomeInfo(request): # 計(jì)算書的平均價(jià)格 average_price = models.Book.objects.aggregate(avg_price = Avg('price')) # 如果不加別名結(jié)果為: {'price__avg': 100.25} # 獲取書的最高價(jià)格 max_price = models.Book.objects.aggregate(Max('price')) # 獲取書的最低價(jià)格 min_price = models.Book.objects.aggregate(min_price = Min('price')) # 統(tǒng)計(jì)書的總數(shù)量 # book_count = models.Book.objects.aggregate(Count('id')) book_count = models.Book.objects.aggregate(book_count = Count('id')) # 其實(shí)也可以使用 len(models.Book.objects.all()) / models.Book.objects.count() # 計(jì)算所有書的總價(jià)格 total_price = models.Book.objects.aggregate(total_price = Sum('price')) return HttpResponse(f"平均價(jià)格: {average_price}, 最高價(jià)格: {max_price}, 最低價(jià)格: {min_price}, 總數(shù)量: {book_count}, 總價(jià)格: {total_price}")
在路由urls.py里面添加
path('getBookSomeInfo', views.getBookSomeInfo, name='getBookSomeInfo'),
訪問鏈接http://127.0.0.1:8082/article/getBookSomeInfo
3.分組查詢(annotate)
1.定義
annotate()
是 Django ORM 提供的一個(gè)方法,用于在查詢集中為每個(gè)對(duì)象添加計(jì)算值。與 aggregate()
方法不同,annotate()
是逐個(gè)對(duì)象進(jìn)行計(jì)算,而 aggregate()
是對(duì)整個(gè)查詢集進(jìn)行計(jì)算,并返回一個(gè)匯總結(jié)果
2.使用
使用前要先從 django.db.models 引入聚合函數(shù),annotate()
方法接受一個(gè)或多個(gè)聚合函數(shù)作為參數(shù),這些聚合函數(shù)會(huì)被應(yīng)用到查詢集中,并將結(jié)果作為額外字段添加到每個(gè)對(duì)象上
queryset.annotate(聚合函數(shù))
3.具體案例
我們先修改一下剛剛定義的Book模型,同時(shí)增加一個(gè)作者User模型
class User(models.Model): name = models.CharField(max_length=255) # 作者名稱 def __str__(self): return self.name class Book(models.Model): title = models.CharField(max_length=255) # 書名 # author = models.CharField(max_length=255) # 作者 user = models.ForeignKey(User, related_name='books', null=True, on_delete=models.CASCADE) # 作者 price = models.DecimalField(max_digits=10, decimal_places=2) # 價(jià)格 rating = models.FloatField() # 評(píng)分 published_date = models.DateField() # 出版日期 pages = models.IntegerField() # 頁數(shù) def __str__(self): return self.title
執(zhí)行命令生成數(shù)據(jù)表,user表和book表都先手動(dòng)寫入數(shù)據(jù),不通過程序?qū)懭霐?shù)據(jù)
views.py增加方法
def getBookFormUser(request): # 計(jì)算每個(gè)作者的書籍?dāng)?shù)量 # 這里的 'books' 是 models.User 類中定義的外鍵名稱,如果外鍵名稱不是 'books' 則需要修改 users_with_book_count = models.User.objects.annotate(book_count = Count('books')) users_with_book_count_str = '' # 輸出每個(gè)作者的書籍?dāng)?shù)量 for user in users_with_book_count: users_with_book_count_str += f"{user.name} has {user.book_count} books.\n" # 計(jì)算每個(gè)作者的書籍平均價(jià)格 # books__price 代表 books 外鍵的 price 字段 users_with_avg_price = models.User.objects.annotate(avg_price = Avg('books__price')) users_with_avg_price_str = '' # 輸出每個(gè)作者的書籍平均價(jià)格 for user in users_with_avg_price: users_with_avg_price_str += f"{user.name} has an average book price of {user.avg_price}.\n" # 計(jì)算每個(gè)作者的書籍總價(jià)格和最高評(píng)分 users_with_totals = models.User.objects.annotate(total_price = Sum('books__price'), highest_rating = Max('books__rating')) users_with_totals_str = '' # 輸出每個(gè)作者的書籍總價(jià)格和最高評(píng)分 for user in users_with_totals: users_with_totals_str += f"{user.name} has a total book price of {user.total_price} and the highest rating is {user.highest_rating}.\n" # 返回帶有換行符的 HTML 響應(yīng),確保編碼為UTF-8 return HttpResponse( f"每個(gè)作者的書籍?dāng)?shù)量: <br>{users_with_book_count_str}<br>" f"每個(gè)作者的書籍平均價(jià)格: <br>{users_with_avg_price_str}<br>" f"每個(gè)作者的書籍總價(jià)格和最高評(píng)分: <br>{users_with_totals_str}", content_type="text/html; charset=utf-8" )
增加路由
path('getBookFormUser', views.getBookFormUser, name='getBookFormUser'),
訪問鏈接http://127.0.0.1:8000/article/getBookFormUser
4.F() 查詢
1.定義
F()
表達(dá)式用于在數(shù)據(jù)庫中直接引用字段的值,而不是將值從數(shù)據(jù)庫取出后再進(jìn)行計(jì)算。它允許你在數(shù)據(jù)庫層面進(jìn)行原子性的計(jì)算操作,從而避免出現(xiàn)競(jìng)爭(zhēng)條件或數(shù)據(jù)不同步的問題,常用于以下場(chǎng)景:
對(duì)字段值進(jìn)行加減、乘除等數(shù)學(xué)運(yùn)算。
比較同一個(gè)模型中不同字段的值。
更新字段時(shí)直接使用該字段的當(dāng)前值。
2.使用
要使用 F() 表達(dá)式,你需要從 django.db.models 中導(dǎo)入 F 類
from django.db.models import F
字段值的更新(如:增加瀏覽數(shù))
先更新一下Book模型
class Book(models.Model): title = models.CharField(max_length=255) # 書名 # author = models.CharField(max_length=255) # 作者 user = models.ForeignKey(User, related_name='books', null=True, on_delete=models.CASCADE) # 作者 price = models.DecimalField(max_digits=10, decimal_places=2) # 價(jià)格 rating = models.FloatField() # 評(píng)分 published_date = models.DateField() # 出版日期 pages = models.IntegerField() # 頁數(shù) views = models.IntegerField(default=0) # 瀏覽量 def __str__(self): return self.title
定義方法和路由
def addViews(request): # 增加閱讀量 article_id = 1 models.Book.objects.filter(id=article_id).update(views=F('views') + 1) return HttpResponse('Views added successfully') path('addViews', views.addViews, name='addViews'),
訪問鏈接http://127.0.0.1:8000/article/addViews
一些其他場(chǎng)景
定義方法和路由
def someOtherInfo(request): # 比較同一個(gè)模型的兩個(gè)字段的值 # 獲取 price 大于 discount_price 的商品,這個(gè)查詢會(huì)返回所有 price 大于 discount_price 的 Product 實(shí)例 # 注意:F() 函數(shù)用于引用其他字段的值,不能用于直接比較兩個(gè)字段的值,price和views都是字段名 book_gt_discount = models.Book.objects.filter(price__gt=F('views')) book_gt_discount_str = '' for item in book_gt_discount: book_gt_discount_str += f"Book {item.id} has a price of {item.price} and views of {item.views}\n" # 多字段運(yùn)算 # 獲取所有books的總價(jià)格和評(píng)分的乘積 # 使用 F() 表達(dá)式在 annotate 中 books = models.Book.objects.annotate(total_price=F('price') * F('views')) str_books = '' for item in books: str_books += f"Book {item.id} has total price {item.total_price}\n" # 查詢時(shí)對(duì)字段進(jìn)行運(yùn)算 # 獲取book的價(jià)格大于其views加500的書籍 high_books = models.Book.objects.filter(price__gt=F('views') + 500.00) high_books_str = '' for item in high_books: high_books_str += f"Book {item.id} has a price of {item.price}\n" return HttpResponse( f"book_gt_discount: <br>{book_gt_discount_str}<br>" f"str_books: <br>{str_books}<br>" f"high_books_str: <br>{high_books_str}", content_type="text/html; charset=utf-8" ) path('someOtherInfo', views.someOtherInfo, name='someOtherInfo'),
訪問鏈接http://127.0.0.1:8000/article/someOtherInfo
5.Q() 查詢
1.定義
Q()
對(duì)象來自 django.db.models
,用于創(chuàng)建復(fù)雜的查詢條件。你可以使用它來結(jié)合多個(gè)條件,執(zhí)行與(AND)或或(OR)操作,甚至是非(NOT)操作,尤其是在需要執(zhí)行“OR”操作或者需要多個(gè)條件組合時(shí)非常有用。Q() 對(duì)象使得構(gòu)建復(fù)雜的查詢變得更加靈活和強(qiáng)大,
使用前還是先導(dǎo)入
from django.db.models import Q
2.查詢
定義方法和路由
def searchByq(request): # 按價(jià)格和閱讀量查詢書籍 # 注意:Q() 函數(shù)用于構(gòu)建復(fù)雜的查詢條件,可以與其他條件組合使用 # 這里的 Q() 函數(shù)與 price__gt 條件組合使用,表示價(jià)格大于 500.00 # 與 views__gt 條件組合使用,表示閱讀量大于 1 books_and = models.Book.objects.filter(Q(price__gt=500.00) & Q(views__gt=1)) books_and_str = '' for item in books_and: books_and_str += f"Book {item.id} has a price of {item.price} and views of {item.views}\n" # 按價(jià)格或閱讀量查詢書籍 # 這里的 Q() 函數(shù)與 price__gt 條件組合使用,表示價(jià)格大于 500.00 # 與 views__gt 條件組合使用,表示閱讀量大于 1 books_or = models.Book.objects.filter(Q(price__gt=500.00) | Q(views__gt=1)) books_or_str = '' for item in books_or: books_or_str += f"Book {item.id} has a price of {item.price} and views of {item.views}\n" # 按價(jià)格范圍查詢書籍 # 這里的 Q() 函數(shù)與 price__range 條件組合使用,表示價(jià)格在 500.00 到 1000.00 之間 books_range = models.Book.objects.filter(Q(price__range=(500.00, 1000.00))) books_range_str = '' for item in books_range: books_range_str += f"Book {item.id} has a price of {item.price}\n" # not 查詢 這里使用的 ~Q() 函數(shù)表示價(jià)格不大于 500.00 books_not = models.Book.objects.filter(~Q(price__gt=500.00)) books_not_str = '' for item in books_not: books_not_str += f"Book {item.id} has a price of {item.price}\n" return HttpResponse( f"books_and_str: <br>{books_and_str}<br>" f"books_or_str: <br>{books_or_str}<br>" f"books_range_str: <br>{books_range_str}" f"books_not_str: <br>{books_not_str}", content_type="text/html; charset=utf-8" ) path('searchByq', views.searchByq, name='searchByq'),
訪問鏈接http://127.0.0.1:8000/article/searchByq
到此這篇關(guān)于Django 聚合查詢的文章就介紹到這了,更多相關(guān)Django 聚合查詢內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Keras目標(biāo)檢測(cè)mtcnn?facenet搭建人臉識(shí)別平臺(tái)
這篇文章主要為大家介紹了Keras目標(biāo)檢測(cè)mtcnn?facenet搭建人臉識(shí)別平臺(tái),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05tensorflow 使用flags定義命令行參數(shù)的方法
本篇文章主要介紹了tensorflow 使用flags定義命令行參數(shù)的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-04-04Python中如何實(shí)現(xiàn)MOOC掃碼登錄
這篇文章主要介紹了Python中如何實(shí)現(xiàn)MOOC掃碼登錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01Pytorch實(shí)現(xiàn)LSTM案例總結(jié)學(xué)習(xí)
這篇文章主要介紹了Pytorch實(shí)現(xiàn)LSTM案例總結(jié)學(xué)習(xí),文章通過構(gòu)建網(wǎng)絡(luò)層、前向傳播forward()展開主題介紹,需要的小伙吧可以參考一下2022-07-07導(dǎo)入pytorch時(shí)libmkl_intel_lp64.so找不到問題解決
這篇文章主要為大家介紹了導(dǎo)入pytorch時(shí)libmkl_intel_lp64.so找不到問題解決示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06pandas讀取csv文件,分隔符參數(shù)sep的實(shí)例
今天小編就為大家分享一篇pandas讀取csv文件,分隔符參數(shù)sep的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-12-12Pyecharts 中Geo函數(shù)常用參數(shù)的用法說明
這篇文章主要介紹了Pyecharts 中Geo函數(shù)常用參數(shù)的用法說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-02-02Python一鍵查找iOS項(xiàng)目中未使用的圖片、音頻、視頻資源
這篇文章主要介紹了Python-一鍵查找iOS項(xiàng)目中未使用的圖片、音頻、視頻資源,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2019-08-08