学习模型准备:
from django.db import models class Author(models.Model): """作者模型""" name = models.CharField(max_length=100) age = models.IntegerField() email = models.EmailField() class Meta: db_table = 'author' class Publisher(models.Model): """出版社模型""" name = models.CharField(max_length=300) class Meta: db_table = 'publisher' class Book(models.Model): """图书模型""" name = models.CharField(max_length=300) pages = models.IntegerField() price = models.FloatField() rating = models.FloatField() author = models.ForeignKey(Author,on_delete=models.CASCADE) publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE) class Meta: db_table = 'book' class BookOrder(models.Model): """图书订单模型""" book = models.ForeignKey("Book",on_delete=models.CASCADE) price = models.FloatField() create_time = models.DateTimeField(auto_now_add=True,null=True) class Meta: db_table = 'book_order'
1. 所有的聚合函数都是放在`django.db.models`下面。
例如:
from django.db.models import Avg,Count,Max,Min,Sum 2. 聚合函数不能够单独的执行,需要放在一些可以执行聚合函数的方法下面中去执行。比如`aggregate`‘annotate’和。示例代码如下: ```python result = Book.objects.aggregate(Avg("price")) ``` 3. 聚合函数执行完成后,给这个聚合函数的值取个名字。取名字的规则,默认是`filed+__+聚合函数名字`形成的。比如以上代码形成的名字叫做`price__avg`。如果不想使用默认的名字,那么可以在使用聚合函数的时候传递关键字参数进去,参数的名字就是聚合函数执行完成的名字。实示例代码如下: ```python result = Book.objects.aggregate(avg=Avg("price")) ``` avg=为给这个Avg("price") 取得名字! 以上传递了关键字参数`avg=Avg("price")`,那么以后`Avg`聚合函数执行完成的名字就叫做`avg`。 result 返回一个字典:{'avg': 97.25} 底层SQL语句: [{'sql': 'SELECT @@SQL_AUTO_IS_NULL', 'time': '0.001'}, {'sql': 'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED', 'time': '0.001'}, {'sql': 'SELECT AVG(`book`.`price`) AS `avg` FROM `book`', 'time': '0.463'}] 例如:
def index(request):
# 获取所有图书的定价的平均价
result = Book.objects.aggregate(avg=Avg("price"))
print(result)
# QuerySet
# print(result.query)
print(connection.queries) #打印SQL语句
return HttpResponse("index")
4. `aggregate`:这个方法不会返回一个`QuerySet`对象,而是返回一个字典。这个字典中的key就是聚合函数的名字,值就是聚合函数执行后的结果。{'avg': 97.25}
5. `aggregate`和`annotate`的相同和不同: * 相同:这两个方法都可以执行聚合函数。 * 不同: - `aggregate`返回的是一个字典,在这个字典中存储的是这个聚合函数执行的结果。而`annotate`返回的是一个`QuerySet`对象,并且会在查找的模型上添加一个聚合函数的属性。 - `aggregate`不会做分组,而`annotate`会使用`group by`子句进行分组,只有调用了`group by`子句,才能对每一条数据求聚合函数的值。
例如:
def index2(request):
books = Book.objects.annotate(avg=Avg("bookorder__price")) #bookorder 为Book模型所关联的Bookorder模型名小写,__ 双下划线为精确查找目标字典名字,精确查找可以省略exac for book in books: #annotate查出来是分组数据,需要遍历 print('%s/%s'%(book.name,book.avg)) print(connection.queries) return HttpResponse("index2")
3
登陆后方可评论