如何在Django中计算过滤查询的带注释比例?

时间:2016-04-14 20:47:03

标签: django aggregate-functions

对于民意调查应用,我想要product_codeCount()和产品评级的提示>每个产品评级为3(" Product_r")对象(在product_code上分组)。

我希望我能在最后一个注释表达式中计算出来,但似乎没有。

q = Product_r.objects.all()\
    .annotate(product_code=F('fk_product__product_code'))\
    .values('product_code')\
    .annotate(count=Count('id'))\
    .annotate(proportion=Count(score__gt=3)/count)

以下尝试也不起作用(抱怨count未定义,并且还会过滤整个查询,而不仅仅是计算比例的后续注释部分):

q = Product_r.objects.all()\
    .annotate(product_code=F('fk_product__product_code'))\
    .values('product_code')\
    .annotate(count=Count('id'))\
    .filter(score__gt=3)\
    .annotate(proportion=Count('id')/count)

有没有办法在不对代码进行两次编码的情况下执行此操作(其中一个对score__gt=3进行过滤),然后将两个count值除以? This blog post使用原始SQL来做这类事情 - 我希望在我的案例中可以避免这种情况。

1 个答案:

答案 0 :(得分:0)

嗯,要在这里投入生产,我使用的解决方案的简化版本。随着表格越来越大,我可能会缩小查询的范围,以便它不可能获取超过N条记录。希望它对某人有用。

#http://stackoverflow.com/a/3422287/3790954
#INNER JOIN two lists of dictionaries based on a common dictionary key
def merge_lists(l1, l2, key):
    merged = {} #will be a dict of dicts, with the primary key being the value to join on
    for item in l1+l2:
        if item[key] in merged:
            merged[item[key]].update(item)  
        else:
            merged[item[key]] = item
    return [v for (k, v) in merged.items()]

@login_required
def tabulate_results(request):
    first_list = Model1.objects.all().values_list('id', 'something', 'something_else')
    second_list = Model2.objects.all().values_list('id', 'other_stuff')
    #perform some sort of list comprehension here to get l1 and l2 
    #with the values you're interested in, then merge.
    merged_list = merge_lists(l1, l2, 'id')
    return render(request, "template.html", {"my_data": merged_list}

然后在template.html中制表,并使用javascript排序(将一些计算工作推送到客户端)。