2017-08-24 5 views
1

私はdjangoとredisを使用してランク付けアプリケーションを作成しています。項目スコアはキー "ranking:id:item_rank"でソートされたセットに格納されています。 Django-debug-toolbarは、インデックスページにランキングとその上位3つの項目を表示すると、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}) 

私はインデックスページで上位3項目を表示するカスタムテンプレートタグを作成します。

#1 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つのランキングがあるので、2つの重複があります。より多くのランキング、より多くの重複。どのようにSQLクエリを減らすには?前もって感謝します。

答えて

0

QuerySetlist()を使用する必要はありません。これにより、Django ORMはリスト内の各項目のクエリを評価し、それをメモリに保持します。

読み取りthis

関連する問題