欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Django Aggregation聚合使用方法解析

 更新時(shí)間:2019年08月01日 10:37:32   作者:再見(jiàn)紫羅蘭  
這篇文章主要介紹了Django Aggregation聚合使用方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

在當(dāng)今根據(jù)需求而不斷調(diào)整而成的應(yīng)用程序中,通常不僅需要能依常規(guī)的字段,如字母順序或創(chuàng)建日期,來(lái)對(duì)項(xiàng)目進(jìn)行排序,還需要按其他某種動(dòng)態(tài)數(shù)據(jù)對(duì)項(xiàng)目進(jìn)行排序。Djngo聚合就能滿足這些要求。

以下面的Model為例

from django.db import models
 
class Author(models.Model):
  name = models.CharField(max_length=100)
  age = models.IntegerField()
class Publisher(models.Model):
  name = models.CharField(max_length=300)
  num_awards = models.IntegerField()
class Book(models.Model):
  name = models.CharField(max_length=300)
  pages = models.IntegerField()
  price = models.DecimalField(max_digits=10, decimal_places=2)
  rating = models.FloatField()
  authors = models.ManyToManyField(Author)
  publisher = models.ForeignKey(Publisher)
  pubdate = models.DateField() 
class Store(models.Model):
  name = models.CharField(max_length=300)
  books = models.ManyToManyField(Book)
  registered_users = models.PositiveIntegerField()

快速了解

# books總數(shù)量.
>>> Book.objects.count()
2452
 
# Total number of books with publisher=BaloneyPress
>>> Book.objects.filter(publisher__name='BaloneyPress').count()
73
 
# books的平均price.
>>> from django.db.models import Avg
>>> Book.objects.all().aggregate(Avg('price'))
{'price__avg': 34.35}
 
# books的最大price.
>>> from django.db.models import Max
>>> Book.objects.all().aggregate(Max('price'))
{'price__max': Decimal('81.20')}
 
# All the following queries involve traversing the Book<->Publisher
# many-to-many relationship backward
 
# 為每個(gè)publisher添加個(gè)num_books屬性,即每個(gè)pulisher出版的book的數(shù)量.
>>> from django.db.models import Count
>>> pubs = Publisher.objects.annotate(num_books=Count('book'))
>>> pubs
[<Publisher BaloneyPress>, <Publisher SalamiPress>, ...]
>>> pubs[0].num_books
73
 
# 根據(jù)num_book屬性排序.
>>> pubs = Publisher.objects.annotate(num_books=Count('book')).order_by('-num_books')[:5]
>>> pubs[0].num_books
1323

聚合生成Generating aggregates over a QuerySet

Django有兩種方法來(lái)生成聚合。第一種方法是為整個(gè)QuerySet生成聚合值,例如為全部的books生成price的平均值:

>>> from django.db.models import Avg
>>> Book.objects.all().aggregate(Avg('price'))
{'price__avg': 34.35}

可以簡(jiǎn)略為:

>>> Book.objects.aggregate(Avg('price'))
{'price__avg': 34.35}

函數(shù)aggregate()的參數(shù)是一系列聚合函數(shù)aggregate functions:

Avg

返回平均值

Count

class Count(field, distinct=False)

返回計(jì)數(shù)。當(dāng)參數(shù)distinct=True時(shí),返回unique的對(duì)象數(shù)目。

Max

返回最大值

Min

返回最小值.

StdDev

class StdDev(field, sample=False)

返回標(biāo)準(zhǔn)偏差

有一個(gè)參數(shù)sample

默認(rèn)情況下sample=False,返回總體標(biāo)準(zhǔn)偏差,如果sample=True,返回樣本標(biāo)準(zhǔn)偏差。

Sum

返回總值

Variance

class Variance(field, sample=False)

返回方差

有一個(gè)參數(shù)sample,默認(rèn)返回總體方差,sample設(shè)為T(mén)rue時(shí)返回樣本方差。

aggregate()方法被調(diào)用時(shí),返回一個(gè)鍵值對(duì)字典,可以指定key的名字:

>>> Book.objects.aggregate(average_price=Avg('price'))
{'average_price': 34.35}

如果你想生成多個(gè)聚合,你只需要添加另一個(gè)參數(shù)。所以,如果我們還想知道所有書(shū)的最高和最低的價(jià)格:

>>> from django.db.models import Avg, Max, Min
>>> Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
{'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}

為查詢集的每個(gè)對(duì)象生成聚合值Generating aggregates for each item in a QuerySet

這是生成聚合值的第二種方法。比如你要檢索每本書(shū)有多少個(gè)作者。book和author是manytomany的關(guān)系,我們可以為每本書(shū)總結(jié)出這種關(guān)系。

每個(gè)對(duì)象的總結(jié)可以用方法annotate()生成:

# 建立一個(gè)annotate QuerySet
>>> from django.db.models import Count
>>> q = Book.objects.annotate(Count('authors'))
# 第一個(gè)對(duì)象
>>> q[0]
<Book: The Definitive Guide to Django>
>>> q[0].authors__count
2
# 第二個(gè)對(duì)象
>>> q[1]
<Book: Practical Django Projects>
>>> q[1].authors__count
1

也可以指定生成屬性的名字:

>>> q = Book.objects.annotate(num_authors=Count('authors'))
>>> q[0].num_authors
2
>>> q[1].num_authors
1

和aggregate()不同,annotate()的輸出是一個(gè)QuerySet。

聯(lián)合聚合Joins and aggregates

目前為止,我們聚合查詢的field都屬于我們要查詢的Model,我們也可以用其它Model的field來(lái)進(jìn)行聚合查詢,例如:

>>> from django.db.models import Max, Min
>>> Store.objects.annotate(min_price=Min('books__price'), max_price=Max('books__price'))

這樣就可以查詢每個(gè)Store里面books的價(jià)格范圍

聯(lián)合鏈的深度可以隨心所欲:

>>> Store.objects.aggregate(youngest_age=Min('books__authors__age'))

反向關(guān)系Following relationships backwards

通過(guò)book反向查詢publisher:

>>> from django.db.models import Count, Min, Sum, Avg
>>> Publisher.objects.annotate(Count('book'))

返回的QuerySet的每個(gè)publisher都會(huì)帶一個(gè)屬性book_count。

查詢出版最久的書(shū)的出版日期:

>>> Publisher.objects.aggregate(oldest_pubdate=Min('book__pubdate'))

查詢每個(gè)作者寫(xiě)的書(shū)的總頁(yè)數(shù):

>>> Author.objects.annotate(total_pages=Sum('book__pages'))

查詢所有作者寫(xiě)的書(shū)的平均rating:

>>> Author.objects.aggregate(average_rating=Avg('book__rating'))

聚合和其它查詢集操作Aggregations and other QuerySet clauses

filter() and exclude()

聚合可以和filter和exclude一起使用:

>>> from django.db.models import Count, Avg
>>> Book.objects.filter(name__startswith="Django").annotate(num_authors=Count('authors'))
>>> Book.objects.filter(name__startswith="Django").aggregate(Avg('price'))

可以根據(jù)聚合值進(jìn)行篩選:

>>> Book.objects.annotate(num_authors=Count('authors')).filter(num_authors__gt=1)

編寫(xiě)一個(gè)包含annotate()和filter()從句的復(fù)雜查詢時(shí),要特別注意作用于QuerySet的從句的順序順序的不同,產(chǎn)生的意義也不同:

>>> Publisher.objects.annotate(num_books=Count('book')).filter(book__rating__gt=3.0)
>>> Publisher.objects.filter(book__rating__gt=3.0).annotate(num_books=Count('book'))

兩個(gè)查詢都返回了至少出版了一本好書(shū)(評(píng)分大于3分)的出版商的列表。但是第一個(gè)查詢的注解包含其該出版商發(fā)行的所有圖書(shū)的總數(shù);而第二個(gè)查詢的注解只包含出版過(guò)好書(shū)的出版商的所發(fā)行的好書(shū)(評(píng)分大于3分)總數(shù)。在第一個(gè)查詢中,注解在過(guò)濾器之前,所以過(guò)濾器對(duì)注解沒(méi)有影響。

在第二個(gè)查詢中,過(guò)濾器在注解之前,所以,在計(jì)算注解值時(shí),過(guò)濾器就限制了參與運(yùn)算的對(duì)象的范圍

order_by()

可以根據(jù)聚合值進(jìn)行排序:

>>> Book.objects.annotate(num_authors=Count('authors')).order_by('num_authors')

values()

通常,注解annotate是添加到每一個(gè)對(duì)象上的,一個(gè)執(zhí)行了注解操作的查詢集 QuerySet 所返回的結(jié)果中,每個(gè)對(duì)象都添加了一個(gè)注解值。但是,如果使用了values()從句,它就會(huì)限制結(jié)果中列的范圍,對(duì)注解賦值的方法就會(huì)完全不同。就不是在原始的 QuerySet 返回結(jié)果中對(duì)每個(gè)對(duì)象中添加注解,而是根據(jù)定義在 values() 從句中的字段組合對(duì)先結(jié)果進(jìn)行唯一的分組,再根據(jù)每個(gè)分組算出注解值,這個(gè)注解值是根據(jù)分組中所有的成員計(jì)算而得的:

>>> Author.objects.values('name').annotate(average_rating=Avg('book__rating'))

這樣的寫(xiě)法下,QuerySet會(huì)根據(jù)name進(jìn)行組合,返回的是每個(gè)unique name的聚合值。如果有兩個(gè)作者有相同的名字,這兩個(gè)作者會(huì)被當(dāng)做一個(gè)計(jì)算,他們的books會(huì)合在一起。

>>> Author.objects.annotate(average_rating=Avg('book__rating')).values('name', 'average_rating')

位置互換后,會(huì)為每個(gè)author都生成一個(gè)average_rating,而且只會(huì)輸出每個(gè)author的name和average_rating。

默認(rèn)排序下使用聚合:

from django.db import models
 
class Item(models.Model):
  name = models.CharField(max_length=10)
  data = models.IntegerField()
 
  class Meta:
    ordering = ["name"]

如果你想知道每個(gè)非重復(fù)的data值出現(xiàn)的次數(shù),你可能這樣寫(xiě):

# Warning: 不正確的寫(xiě)法
Item.objects.values("data").annotate(Count("id"))

這部分代碼想通過(guò)使用它們公共的data值來(lái)分組Item對(duì)象,然后在每個(gè)分組中得到id值的總數(shù)。但是上面那樣做是行不通的。這是因?yàn)槟J(rèn)排序項(xiàng)中的name也是一個(gè)分組項(xiàng),所以這個(gè)查詢會(huì)根據(jù)非重復(fù)的(data,name)進(jìn)行分組,而這并不是你本來(lái)想要的結(jié)果。所以,你需要這樣寫(xiě)來(lái)去除默認(rèn)排序的影響:

Item.objects.values("data").annotate(Count("id")).order_by()

Aggregating annotations

也可以根據(jù)annotation結(jié)果生成聚合值,例如計(jì)算每本書(shū)平均有幾個(gè)作者:

>>> from django.db.models import Count, Avg
>>> Book.objects.annotate(num_authors=Count('authors')).aggregate(Avg('num_authors'))
{'num_authors__avg': 1.66}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python使用MONGODB入門(mén)實(shí)例

    Python使用MONGODB入門(mén)實(shí)例

    這篇文章主要介紹了Python使用MONGODB的方法,實(shí)例分析了Python使用MONGODB的啟動(dòng)、安裝及使用的相關(guān)技巧,需要的朋友可以參考下
    2015-05-05
  • Python學(xué)生信息管理系統(tǒng)修改版

    Python學(xué)生信息管理系統(tǒng)修改版

    這篇文章主要為大家詳細(xì)介紹了python學(xué)生信息管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • Python 之 Json序列化嵌套類方式

    Python 之 Json序列化嵌套類方式

    今天小編就為大家分享一篇Python 之 Json序列化嵌套類方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-02-02
  • Django微信小程序后臺(tái)開(kāi)發(fā)教程的實(shí)現(xiàn)

    Django微信小程序后臺(tái)開(kāi)發(fā)教程的實(shí)現(xiàn)

    這篇文章主要介紹了Django微信小程序后臺(tái)開(kāi)發(fā)教程的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • python多線程案例之多任務(wù)copy文件完整實(shí)例

    python多線程案例之多任務(wù)copy文件完整實(shí)例

    這篇文章主要介紹了python多線程案例之多任務(wù)copy文件,結(jié)合完整實(shí)例形式分析了Python使用multiprocessing模塊實(shí)現(xiàn)基于多線程的文件拷貝相關(guān)操作技巧,需要的朋友可以參考下
    2019-10-10
  • Python參數(shù)類型以及常見(jiàn)的坑詳解

    Python參數(shù)類型以及常見(jiàn)的坑詳解

    這篇文章主要介紹了Python參數(shù)類型以及常見(jiàn)的坑詳解,由于之前遇到過(guò)幾次有關(guān)于參數(shù)類型的坑,以及經(jīng)常容易把一些參數(shù)類型搞混淆,現(xiàn)在做一下有關(guān)參數(shù)類型的總結(jié)記錄以及對(duì)之前踩坑經(jīng)歷的分析,需要的朋友可以參考下
    2019-07-07
  • Python抓取通過(guò)Ajax加載數(shù)據(jù)的示例

    Python抓取通過(guò)Ajax加載數(shù)據(jù)的示例

    在網(wǎng)頁(yè)上,有一些內(nèi)容是通過(guò)執(zhí)行Ajax請(qǐng)求動(dòng)態(tài)加載數(shù)據(jù)渲染出來(lái)的,本文主要介紹了使用Python抓取通過(guò)Ajax加載數(shù)據(jù),感興趣的可以了解一下
    2023-05-05
  • 卷積神經(jīng)網(wǎng)絡(luò)的發(fā)展及各模型的優(yōu)缺點(diǎn)及說(shuō)明

    卷積神經(jīng)網(wǎng)絡(luò)的發(fā)展及各模型的優(yōu)缺點(diǎn)及說(shuō)明

    這篇文章主要介紹了卷積神經(jīng)網(wǎng)絡(luò)的發(fā)展及各模型的優(yōu)缺點(diǎn)及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Python標(biāo)準(zhǔn)庫(kù)pickle的簡(jiǎn)單使用

    Python標(biāo)準(zhǔn)庫(kù)pickle的簡(jiǎn)單使用

    本文主要介紹了Python標(biāo)準(zhǔn)庫(kù)pickle的簡(jiǎn)單使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • 在Django中Pyecharts生成圖表實(shí)現(xiàn)

    在Django中Pyecharts生成圖表實(shí)現(xiàn)

    pyecharts是支持python的一種可視化,那么在Django中Pyecharts如何生成圖表,主要有兩種方法,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05

最新評(píng)論