对于民意调查应用,我想要product_code
,Count()
和产品评级的提示>每个产品评级为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来做这类事情 - 我希望在我的案例中可以避免这种情况。
答案 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排序(将一些计算工作推送到客户端)。