Django 查询 - 是否可以在数据库级别按公共(public)字段对元素进行分组?

标签 django django-models django-queryset django-aggregation

我有一个如下所示的数据库模型。将数据视为 2 本书,每本书有 3 个评分。

class Book(models.Model):
    name    = models.CharField(max_length=50)

class Review(models.Model):
    book    = models.ForeignKey(Book)           
    review  = models.CharField(max_length=1000)            
    rating  = models.IntegerField()

问题:是否可以对列表中的所有评分进行分组,每本书都带有 询问。我希望在数据库级别执行此操作,而无需在我的代码中迭代查询集。输出应类似于:
{
 'book__name':'book1', 
 'rating'    : [3, 4, 4], 
 'average'   : 3.66,
 'book__name':'book2', 
 'rating     : [2, 1, 1] ,
 'average'   : 1.33
}

我试过这个查询,但评级既不是按书名分组的,也不是平均正确的:
Review.objects.annotate(average=Avg('rating')).values('book__name','rating','average')

编辑 :补充说明我正在寻找一种在数据库级别对元素进行分组的方法。

最佳答案

你可以这样做。希望这可以帮助。

Review.objects.values('book__name').annonate(average=Avg('rating'))

更新:

如果您想要列表中特定书籍的所有评级,那么您可以这样做。
from collections import defaultdict
ratings = defaultdict(list)
for result in Review.objects.values('book__name', 'rating').order_by('book__name', 'rating'):
    ratings[result['book__name']].append(result['rating'])

你会得到这样的结构:
[{ book__name: [rating1, rating2, ] }, ]

更新:
q = Review.objects.values('book__name').annonate(average=Avg('rating')).filter().prefetech_related('rating')
q[0].ratings.all() # gives all the ratings of a particular book name
q[0].average # gives average of all the ratings of a particular book name

希望这可行(我不确定,抱歉),但您需要添加 related_ name属性
class Review(models.Model):
     book = models.ForeignKey(Book, related_name='rating')

更新:

抱歉,您需要在 SQL 中称为 GROUP_CONCAT 的东西,但目前 Django ORM 不支持它。

您可以使用原始 SQL 或 itertools
from django.db import connection
sql = """
    SELECT name, avg(rating) AS average, GROUP_CONCAT(rating) AS rating
    FROM book JOIN review on book.id = review.book_id
    GROUP BY name
     """
cursor = connection.cursor()
cursor.execute(sql)
data = cursor.fetchall()

DEMO

关于Django 查询 - 是否可以在数据库级别按公共(public)字段对元素进行分组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22343092/

相关文章:

mysql - 如何使用 update() 在 Django 的日期时间字段上增加年份?

python - 选择字段填充错误

python - 接收 "detail": "not found" for detail view with Django Rest Framework

python - 如何使用 Django ORM 在没有数百个查询的情况下选择多对一?

python - psycopg2.errors.UndefinedTable : relation "authentication_author" does not exist: Django v4

python - 为什么值列表在 Django 中保留过滤器?

python - django 查询中的 sql "LIKE"等效项

python - Django error_messages{} 的解释?

python - Django 用户密码未针对自定义用户进行哈希处理

python - 可以在创建时将字典传递给 django 模型吗?