ORM aggregate function details: Count

Keywords: Django SQL

Count: used to find the number of data.

The model used in all of the following examples is:

from django.db import models


# Define author model
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)


# Define publishing house model
class Publisher(models.Model):
    name = models.CharField(max_length=100,unique=True)

    class Meta:
        db_table = 'publisher'


# Define book model
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'


# Define the model of book reservation
class BookOrder(models.Model):
    book = models.ForeignKey('Book', on_delete=models.CASCADE)
    price = models.FloatField()

    class Meta:
        db_table = 'book_order'

1. For example, to calculate the quantity of all books, the following code can be used in the views.py view file:

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. Calculate the number of all books. Because the data in the book table is unique, the number of books can be calculated by calculating the uniqueness of ID.
    count = Book.objects.aggregate(book_count=Count('id'))
    print(count)
    # The result is printed out as: {'book_count': 4}
    return HttpResponse("success !")

2. Number of books to be ordered

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. For the same book quantity, it is also for the book table. Here, it can be for bookorder ufu id or bookorder. The default is to operate on the id field in the book order table
    books = Book.objects.annotate(books_count=Count('bookorder'))
    # print(type(books))
    # <class 'django.db.models.query.QuerySet'>
    # Traverse QuerySet
    for book in books:
        print("%s,%s" % (book.name,book.books_count))
    # Print out the result:
    # Romance of the Three Kingdoms, 2
    # Outlaws of the marsh, 2
    # Dream of the red chamber, 2
    # Journey to the west, 0
# Print out native SQL statements
    print(connection.queries)
# Book '. ` publisher ` ID', count (` book order '. ` ID') as ` books ` count ` from ` book ` L EFT 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. Also Count() can pass the parameter distinct. By default, distinct=False. You can delete the same data in the return value by specifying distinct=True. For example: how many kinds of books are there for the book to be ordered? The example code is as follows:

from django.http import HttpResponse
from .models import Book
from django.db.models import Count


def index(request):
# 6. How many kinds of books are there
# First, you can use annotate() to group, and then delete the same data.
    book_nums = Book.objects.annotate(book_nums=Count('bookorder', distinct=True))
    print(book_nums)
    return HttpResponse("success !")
Print out the result:

The printed result is a QuerySet object, which is not easy to distinguish specific data information. So we can rewrite the Book model's STR self method.

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

Override the str self method of the model:

# Define publishing house model
class Publisher(models.Model):
    name = models.CharField(max_length=100,unique=True)

    class Meta:
        db_table = 'publisher'

    def __str__(self):
        return " ->:%s" % self.name


# Define book model
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 "(Title:%s,The number of pages:%s,Price:%s,Discount:%s,Author:%s,Press:%s)" % (self.name, self.pages, self.price, self.rating, self.author, self.publisher)

Print out the result:
<QuerySet [
< book: (Title: Romance of Three Kingdoms, page number: 893, price: 129.0, Discount: 0.8, author: Luo Guanzhong, 47312587329@qq.com, press: - > Tsinghua University Press) >, 
< book: (Title: outlaws of the marsh, page number: 983, price: 159.0, Discount: 0.75, author: Shi Naian, 571924572@qq.com, press: - > Jilin University Press) >, 
< book: (Title: Hongloumeng, page number: 1543, price: 199.0, Discount: 0.85, author: Cao Xueqin, 42123521472@qq.com, press: - > Zhejiang University Press) >, 
< book: (Title: Journey to the west, page number: 1003, price: 159.0, Discount: 0.75, author: Wu Chengen, 34193452272@qq.com, press: - > Tsinghua University Press) >
]>

Published 93 original articles, won praise 2, visited 3406
Private letter follow

Posted by digitalalpha on Mon, 03 Feb 2020 05:59:44 -0800