2017-08-24 134 views
1

我使用django和redis來構建一個排名應用程序,項目得分存儲在一個排序集中,使用鍵「ranking:id:item_rank」。 Django的調試工具欄說,當我顯示排名及其索引頁面中的前三項時,SQL查詢有重複。Django重複的SQL查詢

#models.py

class Ranking(models.Model): 
    title = models.CharField(max_length=16, unique=True) 
class Item(models.Model): 
    title = models.CharField(max_length=128) 
    ranking = models.ForeignKey(Ranking, related_name='items') 

#的views.py

def index(request): 
    rankings = Ranking.objects.all() 
    return render(request, 'myapp/index.html', {'rankings': rankings}) 

創建自定義的模板標籤來顯示索引頁頂部的三個項目。

#templatetags/ranking_tags.py

r = redis.StrictRedis(host=settings.REDIS_HOST, 
         port=settings.REDIS_PORT, 
         db=settings.REDIS_DB) 

@register.assignment_tag 
def get_top_3(ranking): 
    item_rank = r.zrange('ranking:{}:item_rank'.format(ranking.id), 0, 2, desc=True) 
    item_ids = [int(id) for id in item_rank] 
    items = list(Item.objects.filter(id__in=item_ids)) 
    text = '' 
    try: 
     text = '<p>#1 :' + items[0].title + '</p>' 
     text = text + '<p>#2 :' + items[1].title + '</p>' 
     text = text + '<p>#3 :' + items[2].title + '</p>' 
    except: 
     pass 
    return text 

#index.html的

{% for ranking in rankings %} 
    <div> 
    <h4>{{ ranking.title }}</h4> 
    </div> 
    <div> 
    {% autoescape off %} 
    <div> 
     {% get_top_3 ranking %} 
    </div> 
    {% endautoescape %} 
    </div>  
{% endfor %} 

#Django的調試工具欄

1.SELECT "myapp_ranking"."id", "myapp_ranking"."title" FROM "myapp_ranking" 
2.SELECT "myapp_item"."id", "myapp_item"."title" FROM "myapp_item" WHERE "myapp_item"."id" IN ('1', '2', '5') 
Duplicated 2 times. 
3.SELECT "myapp_item"."id", "myapp_item"."title" FROM "myapp_item" WHERE "myapp_item"."id" IN ('8', '10', '7') 
Duplicated 2 times. 

現在我有2個數據庫的排名,所以有兩個重複。更多排名,更多重複。如何減少sql查詢?提前致謝。

回答

0

QuerySet沒有必要使用list(),它使得Django ORM評估列表中每個項目的查詢,然後將其保存在內存中。

閱讀this