姜戈。如何优化数据库查询?

Posted

技术标签:

【中文标题】姜戈。如何优化数据库查询?【英文标题】:Django. How I can optimize db query? 【发布时间】:2016-05-02 20:18:34 【问题描述】:

我有两个模型:

class Status(models.Model): 

     CHOISES = ( 
         ('new', 'New'), 
         ('in_progress', 'InProgress'), 
         ('on_review', 'OnReview'), 
         ('tested', 'Tested'), 
         ('delivered', 'Delivered') 
     ) 

    status_type = models.CharField( 
    max_length=11, 
    choices=CHOISES, 
    primary_key=True) 

class Task(models.Model):
    name = models.CharField(max_length=200, blank=False)
    status = models.ForeignKey(status)

我的部分观点:

def task_list(request):

    all_tasks = Task.objects.all()
    tasks = 

    tasks['new'] = all_tasks.filter(status_id='new')
    tasks['in_progress'] = all_tasks.filter(status_id='in_progress')
    tasks['on_review'] = all_tasks.filter(status_id='on_review')
    tasks['tested'] = all_tasks.filter(status_id='tested')
    tasks['delivered'] = all_tasks.filter(status_id='delivered')
....

我的模板的一部分:

% for item in new %
    <div id=" item.pk ">
         item.name 
    </div>
% endfor %
</div>
% for item in in_progress %
    <div id=" item.pk ">
         item.name 
    </div>
% endfor %  
.....      

问题是,有什么方法可以优化我的所有查询集,还是不可能为一个数据库调用选择五个过滤器? 据我了解,如果我只在视图中保存此调用all_tasks = Task.objects.all(),然后将逻辑放入模板中,如下所示:

% for item in all_task %
% if item.status_id == "new" %
....

这也将是五个电话 希望我的问题不要太宽泛

【问题讨论】:

【参考方案1】:

只需按视图中的状态对任务进行分组:

from itertools import groupby

def task_list(request):
    all_tasks = Task.objects.select_related('status').order_by('status')
    tasks = status: list(tasks)
             for status, tasks
             in groupby(all_tasks, lambda x: x.status)

并在您的模板中使用它们,例如:

% for task in tasks.new %
   task 
% endfor %

【讨论】:

太棒了!谢谢。也许这是一个愚蠢的问题,但是我现在如何在模板中获取任务对象?我不需要订购单,一件一件的物品。我需要为每个状态将对象放在五列中,就像在 trello.com 中一样,所以我需要一些条件。如果我使用% if % 标记检查状态名称,它仍然是db call? 查询集应该是Task.objects.select_related('status').order_by('status')。在这种情况下,不会有额外的数据库查询。【参考方案2】:

一种可能性是更改您的CHOICES(其中的错字)以映射到对排序有意义的东西,例如整数。

然后使用 orderby 执行单个查询,并在模板中使用 ifchanged 标签。

无论你尝试什么,小心不要陷入在 Django 中实现 SQL 逻辑的陷阱,只是为了避免额外的查询。

无论如何,我建议您使用django-debug-toolbar 之类的东西来掌握任何替代方案的时间。

【讨论】:

以上是关于姜戈。如何优化数据库查询?的主要内容,如果未能解决你的问题,请参考以下文章

空查询返回数据库中的所有字段。姜戈

姜戈。如何在查询结果中添加字段?

你可以制作一个返回查询集的自定义模板标签吗?如果是,如何? - 姜戈

姜戈。 Q 分类查询

姜戈。查询。用引号转义字符串错误

对查询集进行排序的好方法? - 姜戈