zoukankan      html  css  js  c++  java
  • 73.Python中ORM聚合函数详解:Count

    Count:用来求某个数据的个数。

    在以下所有的示例中所采用的模型为:

    from django.db import models
    
    
    # 定义作者模型
    class Author(models.Model):
        name = models.CharField(max_length=100, unique=True)
        age = models.IntegerField()
        email = models.EmailField()
    
        class Meta:
            db_table = 'author'
    
        def __str__(self):
            return "%s,%s,%s" % (self.name,self.age, self.email)
    
    
    # 定义出版社模型
    class Publisher(models.Model):
        name = models.CharField(max_length=100,unique=True)
    
        class Meta:
            db_table = 'publisher'
    
    
    # 定义图书模型
    class Book(models.Model):
        name = models.CharField(max_length=100, unique=True)
        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()
    
        class Meta:
            db_table = 'book_order'
    

    1. 比如:求所有图书的数量,那么views.py视图文件中可以使用以下代码:

    from django.http import HttpResponse
    from .models import Author,Publisher,Book,BookOrder
    from django.db.models import Avg,Count,Sum
    from django.db import connection
    
    
    def index(request):
    # 4.求所有图书的数量,因为book表中的数据具有唯一性所以可以通过计算ID的唯一性来计算图书的数量。
        count = Book.objects.aggregate(book_count=Count('id'))
        print(count)
        # 打印出结果为:{'book_count': 4}
        return HttpResponse("success !")
    
    

    2.求同一种书预定的数量

    from django.http import HttpResponse
    from .models import Author,Publisher,Book,BookOrder
    from django.db.models import Avg,Count,Sum
    from django.db import connection
    
    
    def index(request):
    # 5.求同一种书的预定数量,同样还是针对book表,此处可以是针对bookorder__id,也可以是bookorder。默认就是针对book__order表中id字段进行操作
        books = Book.objects.annotate(books_count=Count('bookorder'))
        # print(type(books))
        # <class 'django.db.models.query.QuerySet'>
        # 遍历QuerySet
        for book in books:
            print("%s,%s" % (book.name,book.books_count))
        # 打印出结果:
        # 三国演义,2
        # 水浒传,2
        # 红楼梦,2
        # 西游记,0
    # 打印出原生SQL语句
        print(connection.queries)
    # 打印出结果:[{'sql': 'SELECT @@SQL_AUTO_IS_NULL', 'time': '0.000'}, {'sql': 'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED', 'time': '0.000'}, {'sql': 'SELECT `book`.`id`, `book`.`name`, `book`.`pages`, `book`.`price`, `book`.`rating`, `book`.`author_id`, `book`.`publisher_id`, COUNT(`book_order`.`id`) AS `books_count` FROM `book` LEFT OUTER JOIN `book_order` ON (`book`.`id` = `book_order`.`book_id`) GROUP BY `book`.`id` ORDER BY NULL', 'time': '0.000'}]
        return HttpResponse("success !")
    
    

    3. 同样Count()可以传递参数distinct,默认情况下,distinct=False.可以通过指定distinct=True,删除返回值中相同的数据。例如:求被预定的书有多少种书,示例代码如下:

    from django.http import HttpResponse
    from .models import Book
    from django.db.models import Count
    
    
    def index(request):
    # 6.求被预定的书都有多少种书
    # 首先可以使用annotate()进行分组,之后对分组的数据进行删除相同的数据操作。
        book_nums = Book.objects.annotate(book_nums=Count('bookorder', distinct=True))
        print(book_nums)
        return HttpResponse("success !")
    
    打印出结果:

    打印出的结果为QuerySet对象,不容易分辨具体的数据信息。因此我们可以对Book模型的__str__(self)方法进行重写。

    <QuerySet [<Book: Book object (1)>, 
    <Book: Book object (2)>, 
    <Book: Book object (3)>, 
    <Book: Book object (4)>]>
    
    

    重写模型的__str__(self)方法:

    # 定义出版社模型
    class Publisher(models.Model):
        name = models.CharField(max_length=100,unique=True)
    
        class Meta:
            db_table = 'publisher'
    
        def __str__(self):
            return " ->:%s" % self.name
    
    
    # 定义图书模型
    class Book(models.Model):
        name = models.CharField(max_length=100, unique=True)
        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'
    
        def __str__(self):
            return "(书名:%s,页数:%s,价格:%s,打折:%s,作者:%s,出版社:%s)" % (self.name, self.pages, self.price, self.rating, self.author, self.publisher)
    
    
    打印出结果:
    <QuerySet [
    <Book: (书名:三国演义,页数:893,价格:129.0,打折:0.8,作者:罗贯中,47,312587329@qq.com,出版社: ->:清华大学出版社)>, 
    <Book: (书名:水浒传,页数:983,价格:159.0,打折:0.75,作者:施耐庵,57,1924572@qq.com,出版社: ->:吉林大学出版社)>, 
    <Book: (书名:红楼梦,页数:1543,价格:199.0,打折:0.85,作者:曹雪芹,42,123521472@qq.com,出版社: ->:浙江大学出版社)>, 
    <Book: (书名:西游记,页数:1003,价格:159.0,打折:0.75,作者:吴承恩,34,193452272@qq.com,出版社: ->:清华大学出版社)>
    ]>
    
    
    始于才华,忠于颜值;每件事情在成功之前,看起来都是天方夜谭。一无所有,就是无所不能。
  • 相关阅读:
    [原创] 扩展jquery-treegrid插件, 实现勾选功能和全删按钮.
    [原创]多版本Java环境变量的配置
    [转]Redmine 配置163邮箱
    [转] --- Error: “A field or property with the name was not found on the selected data source” get only on server
    服务器控件中使用<%#...>, JS和html控件中使用<%=...>
    【字源大挪移—读书笔记】 第三部分:字尾
    【字源大挪移—读书笔记】 第二部分:字根
    使用WebClient 或者 HttpWebRequest均报:"The Remote name can't be solved"
    【字源大挪移—读书笔记】 第一部分:字首
    【英语魔法俱乐部——读书笔记】 3 高级句型-简化从句&倒装句(Reduced Clauses、Inverted Sentences) 【完结】
  • 原文地址:https://www.cnblogs.com/guyan-2020/p/12257662.html
Copyright © 2011-2022 走看看