Django笔记——操作数据库(ORM)第六节

Django笔记

操作数据库——ORM模型中的聚合函数查询

一、模型准备

from django.db import models

class GameCreator(models.Model):
    username = models.CharField(max_length=200)
    email = models.EmailField(unique=True)

class Game(models.Model):
    name = models.CharField(max_length=100)
    price = models.FloatField(default=0)
    creator = models.ForeignKey(GameCreator, on_delete=models.CASCADE, related_name='games')

    class Meta:
        db_table = 'game_table'

在这个设置中,Game 模型通过 ForeignKey 关联到 GameCreator 模型,表示一个游戏创作者可以创建多个游戏,而每个游戏仅属于一个游戏创作者。

二、聚合函数

Django 提供了多种聚合函数,这些函数位于 django.db.models 模块中,用于执行各种统计计算。

2.1 Avg:平均值

知识点Avg 用于计算某个字段的平均值。

示例:计算所有游戏的平均价格。

from django.db.models import Avg

average_price = Game.objects.aggregate(avg_price=Avg('price'))
print(f"Average game price: {average_price['avg_price']}")
2.2 Count:计数

知识点Count 用于计算记录的数量。

示例:计算某个游戏创作者创建的游戏数量。

from django.db.models import Count

creator = GameCreator.objects.first()  # 获取第一个游戏创作者
game_count = creator.games.count()
print(f"The first creator has created {game_count} games.")

或者使用 annotate() 来为每个游戏创作者标注其创建的游戏数量:

creators_with_game_count = GameCreator.objects.annotate(game_count=Count('games'))
for creator in creators_with_game_count:
    print(f"{creator.username} has created {creator.game_count} games.")
2.3 Max 和 Min:最大值和最小值

知识点MaxMin 分别用于找出某个字段的最大值和最小值。

示例:找出最贵和最便宜的游戏。

from django.db.models import Max, Min

max_price = Game.objects.aggregate(Max('price'))
min_price = Game.objects.aggregate(Min('price'))
print(f"Most expensive game price: {max_price['price__max']}")
print(f"Least expensive game price: {min_price['price__min']}")
2.4 Sum:总和

知识点Sum 用于计算某个字段的总和。

示例:计算所有游戏的总价。

from django.db.models import Sum

total_price = Game.objects.aggregate(Sum('price'))
print(f"Total price of all games: {total_price['price__sum']}")

三、aggregate 和 annotate

使用 aggregate()

知识点aggregate() 对整个 QuerySet 进行汇总计算,并返回一个包含汇总结果的字典。

示例:计算所有游戏的平均价格(已在 2.1 中展示),这里不再重复。

使用 annotate()

知识点annotate() 为 QuerySet 中的每个对象添加汇总值作为新属性。

示例:为每个游戏创作者标注其创建的游戏数量(已在 2.2 中展示),这里提供另一个示例,计算每个游戏创作者创建的游戏的平均价格:

creators_with_avg_game_price = GameCreator.objects.annotate(avg_game_price=Avg('games__price'))
for creator in creators_with_avg_game_price:
    print(f"{creator.username}'s games have an average price of {creator.avg_game_price}")

四、F表达式和Q表达式

使用 F 表达式

知识点F 表达式允许您在不将值加载到 Python 内存的情况下引用模型字段,适用于批量更新或避免竞态条件。

示例:假设我们要增加每位游戏创作者所创建游戏的价格(例如,进行批量更新):

from django.db.models import F

# 增加每个游戏的价格10元
Game.objects.update(price=F('price') + 10)
使用 Q 表达式

知识点Q 表达式允许您构建复杂的查询条件,特别是在需要使用 AND、OR 等逻辑运算符时。

示例:查找价格大于50的游戏或者名称包含“冒险”的游戏:

from django.db.models import Q

games = Game.objects.filter(Q(price__gt=50) | Q(name__contains='冒险'))
for game in games:
    print(f"Game: {game.name}, Price: {game.price}")

复杂查询的例子,查找价格在50到100之间的游戏,并且排除名称为空的游戏:

games = Game.objects.filter(Q(price__gte=50) & Q(price__lte=100) & ~Q(name=''))
for game in games:
    print(f"Game: {game.name}, Price: {game.price}")

小结

  • 聚合函数 提供了强大的数据汇总能力,使得用户可以轻松地从数据库中提取统计信息。
  • aggregate() 方法用于对整个 QuerySet 进行汇总计算。
  • annotate() 方法为每个 QuerySet 对象添加汇总值作为新属性,适用于需要为每个对象附加汇总信息的场景。
  • F 表达式 可以用来优化数据库操作,特别是在执行批量更新时。
  • Q 表达式 使得构建复杂查询条件成为可能,尤其是在需要使用 AND、OR 等逻辑运算符时。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值