You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django查询需求:按ID取最新创建对象并汇总字段+球队关联游戏取最新日期

Django查询需求解决方案

针对你提到的两个Django查询需求,我来一步步给你拆解实现方法:


需求1:查询每个ID对应的最新创建对象,并对其他字段求和

这个需求的核心是先锁定每个ID下最新创建的那条记录,再基于该ID进行字段求和(比如示例中的points)。这里我们用Subquery和聚合函数来实现:

假设你的模型结构如下(方便对应示例):

class Game(models.Model):
    id = models.IntegerField()  # 这里指用户标识ID,若用Django默认主键可改为player_id等
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    date_created = models.DateTimeField()
    points = models.IntegerField()
    team = models.ForeignKey('Team', on_delete=models.CASCADE)

实现代码:

from django.db.models import Subquery, OuterRef, Max, Sum

# 第一步:子查询获取每个ID对应的最新创建日期
latest_dates = Game.objects.filter(id=OuterRef('id')).values('id').annotate(latest_date=Max('date_created')).values('latest_date')

# 第二步:筛选出每个ID的最新记录,同时对该ID的points字段求和
result = Game.objects.filter(date_created=Subquery(latest_dates)).values('id', 'first_name', 'last_name').annotate(total_points=Sum('points'))

代码说明:

  1. 子查询latest_dates会为每个ID计算出最大的date_created值;
  2. 主查询通过date_created=Subquery(latest_dates)筛选出每个ID的最新记录;
  3. 最后用annotate(Sum('points'))对该ID下的所有points求和(如果需要仅对最新记录的points求和,去掉Sum直接取字段即可)。

需求2:获取特定Team关联的Games列表,仅保留每个记录的最后一个date_created日期

这个需求是要给指定Team下的每个用户ID,只保留其最新创建的Game记录。同样可以用Subquery或者Window函数实现:

方法一:Subquery方式(性能更优)

from django.db.models import Subquery, OuterRef, Max

# 替换为你要查询的特定Team的ID
target_team_id = 1

# 子查询获取该Team下每个ID的最新创建日期
latest_team_game_dates = Game.objects.filter(
    team_id=target_team_id,
    id=OuterRef('id')
).values('id').annotate(latest_date=Max('date_created')).values('latest_date')

# 筛选出符合条件的最新记录
team_games = Game.objects.filter(
    team_id=target_team_id,
    date_created=Subquery(latest_team_game_dates)
).order_by('id')

方法二:Window函数方式(Django 3.2+支持)

如果你使用的是较新版本的Django,也可以用Window函数来标记每个ID的最新日期,再筛选:

from django.db.models import Window, Max, F

target_team_id = 1

team_games = Game.objects.filter(team_id=target_team_id).annotate(
    # 给每条记录标记其所属ID的最新创建日期
    latest_date=Window(
        expression=Max('date_created'),
        partition_by=['id']  # 按ID分组计算最新日期
    )
).filter(date_created=F('latest_date'))  # 只保留创建日期等于最新日期的记录

效果说明:

针对你提供的示例数据,处理后id=3的记录只会保留date_created="2017-09-18T00:00:00"的那条,不会重复出现同一ID的多条旧记录。


内容的提问来源于stack exchange,提问作者kachus22

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:40:53