2016-04-14 16 views
1

Bir anket uygulaması için, product_code, Count() ve ürün derecelendirme> 3 ürün her bir ürün derecelendirmesi ("Product_r") nesnesini (product_code numaralı grupta) propritesini istiyorum.Django'da bir filtre sorgusunda açıklamalı bir oran nasıl hesaplanır?

Son açıklama ifadesinde bir hesaplama ile kurtulmayı umuyordum, ama öyle değil.

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) 

aşağıdaki girişimi çalışma ya (count tanımlanmamıştır yakınıyor ve ayrıca oranını hesaplar bütün sorgu, sadece takip eden Annotatesekmesindeki parçası filtreler) değildir:

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) 

Sorguyu iki kez kodlamadan (bunlardan biri score__gt=3 filtrelemeden) ve sonra iki count değerini bölen bir yol var mı? This blog post, bu tür bir şey için ham SQL kullanmaktadır - umarım buradaki durumumdan kaçınmak mümkündür.

+0

Saymayı deneyin ('id')/F ('count') '. Çalışacağından emin değilim, ancak tanımlanmayan sayımla ilgili hatayı durduracak. – Alasdair

+0

Haklısın sağol, hatayı durdu. Sorgu yine de doğru çıktıyı üretmez - filtre tüm sorgu için geçerlidir, tüm oranlar eşittir "Sayım (her şey)/Sayım (her şey)" yani 1. – Escher

cevap

0

Peki, bunu üretime sokmak için kullandığım çözümün basitleştirilmiş bir sürümü burada. Tablolar büyüdükçe, muhtemelen sorguların kapsamını azaltacağım, böylece N'den daha fazla kayıt elde etmek mümkün olmayacaktır. Umarım birileri için yararlıdır.

#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} 

Sonra template.html yılında tablolaştırıyoruz ve javascript (istemci üzerine hesaplama çalışmalarının bazı itme) ile sıralamak.

İlgili konular