You need to enable JavaScript to run this app. Django 如何查询特定用户各锻炼动作的最大举重重量
优惠活动
大模型
产品
解决方案
定价
更多

Django 如何查询特定用户各锻炼动作的最大举重重量

实现每个用户对应锻炼动作的最大重量查询

要实现该需求核心使用Django ORM的annotate做分组聚合,和用于全局单值统计的aggregate不同,annotate会按照指定的维度做分组,给每个分组计算对应的聚合值,完全匹配“按锻炼动作分类,取每个分类下用户的最高重量”的场景。

具体查询实现

  • 先理清模型关联链路:
    • Profile 通过一对一关联绑定登录用户
    • Workout 外键关联对应用户的Profile、关联具体的Exercise动作
  • 视图层查询代码示例:
# 先导入需要的聚合方法
from django.db.models import Max

@login_required
def get_user_exercise_max_weight(request):
    # 锁定当前登录用户的Profile,确保只查询私有数据
    current_user_profile = request.user.profile
    
    # 核心查询逻辑
    exercise_max_list = Workout.objects.filter(
        # 过滤条件:只取当前用户的训练记录
        user=current_user_profile
    ).values(
        # 明确分组维度:按锻炼动作的ID、名称做分组
        'exercise__id', 'exercise__name'
    ).annotate(
        # 给每个分组计算最大重量,自定义字段名方便后续模板调用
        personal_max_weight=Max('weight')
    )

    return render(request, 'personal_max.html', {
        'max_weight_list': exercise_max_list
    })

模板层渲染示例

{% for record in max_weight_list %}
<div class="max-weight-card">
    <h4>{{ record.exercise__name }}</h4>
    <p>个人最佳重量:{{ record.personal_max_weight }} kg</p>
</div>
{% endfor %}

常见踩坑提醒

  • 不要直接在全量Workout数据集上做聚合:如果漏掉filter(user=current_user_profile)的条件,会把所有用户的训练数据纳入计算,违反数据私有性要求
  • 不要漏掉values('exercise__id', 'exercise__name')的分组声明:如果没有指定分组维度,Django会默认把每条Workout记录的主键作为分组依据,最终所有聚合结果和原始记录没有区别
  • 不要混淆aggregate和annotate的适用场景:aggregate是对整个查询集计算单个全局统计值(比如全局所有用户的最高卧推重量),annotate才是按维度拆分的分组统计,和当前需求匹配

附带模型优化提示:当前Exercise模型没有关联用户外键,若要实现“锻炼动作也为用户私有”的规则,需要给Exercise增加user = models.ForeignKey(Profile, on_delete=models.CASCADE)字段,创建动作时自动绑定当前用户即可,该改动不影响现有最大重量查询逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.14 13:24:04