Django重复SQL查询

时间:2017-08-24 09:03:02

标签: python django

我正在使用django和redis来构建排名应用程序,项目分数存储在一个排序集中,其密钥为“ranking:id:item_rank”。 Django-debug-toolbar表示当我在索引页面中显示排名及其前三项时,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查询?提前谢谢。

1 个答案:

答案 0 :(得分:0)

不需要在list()上使用QuerySet,它会让Django ORM评估列表中每个项目的查询,然后将其保留在内存中。

阅读this