姜戈。如何优化数据库查询?
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 之类的东西来掌握任何替代方案的时间。
【讨论】:
以上是关于姜戈。如何优化数据库查询?的主要内容,如果未能解决你的问题,请参考以下文章