Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在Django中跨列聚合_Python_Django_Orm_Aggregate - Fatal编程技术网

Python 在Django中跨列聚合

Python 在Django中跨列聚合,python,django,orm,aggregate,Python,Django,Orm,Aggregate,我试图弄清楚是否有一种方法可以使用Django的ORM在Django中进行某种复杂的聚合,或者是否需要使用extra()来插入一些原始SQL 以下是我的对象模型(剥离以显示基本内容): 我想做的是对给定提交的所有投票进行汇总:也就是说,对其任何回复的所有投票,然后还包括将提交标记为最喜欢的人的数量 我让第一部分使用以下代码工作;这将返回每个提交的所有响应的总票数: submission_list = Response.objects\ .values('submission')\ .an

我试图弄清楚是否有一种方法可以使用Django的ORM在Django中进行某种复杂的聚合,或者是否需要使用extra()来插入一些原始SQL

以下是我的对象模型(剥离以显示基本内容):

我想做的是对给定提交的所有投票进行汇总:也就是说,对其任何回复的所有投票,然后还包括将提交标记为最喜欢的人的数量

我让第一部分使用以下代码工作;这将返回每个提交的所有响应的总票数:

submission_list = Response.objects\
  .values('submission')\
  .annotate(votes=Count('voted_up_by'))\
  .filter(votes__gt=0)\
  .order_by('-votes')[:TOP_NUM]
(因此,在获得投票总数后,我将按降序排序,并返回排名靠前的提交,以获得“最佳”列表。)

那部分有效。你有什么办法可以建议在投票中包括赞成每一项提案的人数吗?(为了便于移植,我宁愿避免额外的(),但我认为这可能是必要的,我愿意使用它。)


编辑:在阅读了下面的建议后,我意识到我应该更清楚地描述这个问题。理想的解决方案是允许我按总票数排序(由投票的和受青睐的之和),然后只选择数据库中的前几位。如果不可能,那么我愿意加载每个响应的几个字段,并用Python进行处理;但由于我将处理100000多条记录,因此最好避免这种开销。(还有,对Adam和Dmitry:我很抱歉延迟回复!)

一种可能是稍微重新安排您当前的查询。如果您尝试以下方法会怎么样:

submission_list = Response.objects\
    .annotate(votes=Count('voted_up_by'))\
    .filter(votes__gt=0)\
    .order_by('-votes')[:TOP_NUM]
submission_list.query.group_by = ['submission_id']
这将返回响应对象的查询集(具有相同提交的对象将集中在一起)。为了访问相关提交和/或列表/计数的收藏夹,您有两个选项:

num_votes = submission_list[0].votes
submission = submission_list[0].submission
num_favorite = submission.favorite_of.count()
或者


基本上,第一个选项的好处是仍然是一个queryset,但是您必须确保访问submission对象,以便获得关于提交的任何信息(因为queryset中的每个对象在技术上都是一个响应)。第二个选项的好处是,它是一个包含最喜欢的列表和投票的提交列表,但它不再是一个查询集(因此请确保以后不再需要更改查询)。

一种可能是稍微重新安排当前查询。如果您尝试以下方法会怎么样:

submission_list = Response.objects\
    .annotate(votes=Count('voted_up_by'))\
    .filter(votes__gt=0)\
    .order_by('-votes')[:TOP_NUM]
submission_list.query.group_by = ['submission_id']
这将返回响应对象的查询集(具有相同提交的对象将集中在一起)。为了访问相关提交和/或列表/计数的收藏夹,您有两个选项:

num_votes = submission_list[0].votes
submission = submission_list[0].submission
num_favorite = submission.favorite_of.count()
或者


基本上,第一个选项的好处是仍然是一个queryset,但是您必须确保访问submission对象,以便获得关于提交的任何信息(因为queryset中的每个对象在技术上都是一个响应)。第二个选项的好处是,它是一个包含收藏列表和投票的提交列表,但它不再是一个查询集(因此请确保以后不再需要更改查询)。

您可以在另一个查询中计算收藏,如

favorite_list = Submission.objects.annotate(favorites=Count(favorite_of))
然后添加两个列表中的值:

total_votes = {}
for item in submission_list:
    total_votes[item.submission.id] = item.voted_by
for item in favorite_list:
    has_votes = total_votes.get(item.id, 0)
    total_votes[item.id] = has_votes + item.favorites
我在字典中使用ID,因为提交对象将不相同。如果您需要提交本身,您可以使用一个或多个字典或存储元组(提交、投票),而不仅仅是投票


添加:此解决方案比以前的解决方案更好,因为您只有两个DB请求。

您可以在另一个查询中计算收藏夹,如

favorite_list = Submission.objects.annotate(favorites=Count(favorite_of))
然后添加两个列表中的值:

total_votes = {}
for item in submission_list:
    total_votes[item.submission.id] = item.voted_by
for item in favorite_list:
    has_votes = total_votes.get(item.id, 0)
    total_votes[item.id] = has_votes + item.favorites
我在字典中使用ID,因为提交对象将不相同。如果您需要提交本身,您可以使用一个或多个字典或存储元组(提交、投票),而不仅仅是投票

添加:此解决方案比以前的解决方案更好,因为您只有两个DB请求