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

Django实现好友列表中各用户平均评分查询方法

如何编写查询返回好友列表中每个用户的平均评分

模型定义(models.py)

class Beer(models.Model):
    id = models.BigIntegerField(primary_key=True)
    name = models.CharField(max_length=150)
    ...

class Checkin(models.Model):
    id = models.IntegerField(primary_key=True)
    rating = models.FloatField(blank=True, null=True)
    user = models.ForeignKey(User, on_delete=CASCADE)
    ...

class FriendList(models.Model):
    user = models.OneToOneField(User, on_delete=CASCADE, primary_key=True)
    friend = models.ManyToManyField(User, related_name="friends")

示例数据(PostgreSQL)

存储的签到评分数据如下:

userbeerrating
114.2
113.5
114.0
214.1
213.7

现有实现问题

当前用来获取好友签到记录的查询语句如下:

Checkin.objects.filter(beer=1, user__in=friends.friend.all())

该语句返回单条签到记录的平铺列表,结构类似:

[{user: 1, rating: 4.2}, {user: 1, rating: 3.5},...,{user: 2, rating: 4.1}...]

期望返回按用户聚合的平均评分结果,结构为:

[{user: 1, avg_rating: 4.1}, {user: 2, avg_rating: 3.8}]

正确实现方式

使用Django ORM的分组+聚合功能即可实现,需要先导入Avg聚合函数:

from django.db.models import Avg

# 传入当前用户对应的FriendList实例friends
avg_rating_result = Checkin.objects.filter(
    beer=1,
    user__in=friends.friend.all(),
    # 可选:过滤掉未评分的记录,避免空值干扰计算
    rating__isnull=False
).values("user").annotate(
    avg_rating=Avg("rating")
)

逻辑说明

  • values("user"):指定按关联的用户ID字段对查询结果分组
  • annotate(avg_rating=Avg("rating")):对每个用户分组下的所有rating字段计算平均值,生成名为avg_rating的聚合字段
  • 最终返回的QuerySet迭代后,结构和预期完全一致,可直接使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 14:33:17