姜戈。我如何优化数据库查询?
Django. How I can optimize db query?
我有两个模型:
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 %}
.....
问题是,有没有什么方法可以优化我的所有查询集,或者不可能 select 一次数据库调用有五个过滤器?
据我了解,如果我仅在视图中保存此调用 all_tasks = Task.objects.all()
,然后将逻辑放入模板中,如下所示:
{% for item in all_task %}
{% if item.status_id == "new" %}
....
也将有五次通话
希望我的问题不要太宽泛
只需按您视图中的状态对您的任务进行分组:
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 %}
一种可能性是更改您的 CHOICES
(其中的拼写错误)以映射到对排序有意义的内容,例如整数。
然后使用 orderby 执行单个查询,并在模板中使用 ifchanged
标签。
无论您尝试什么,都请注意不要掉进 Django 中实现 SQL 逻辑的陷阱,只是为了避免额外的查询。
无论如何,我建议您使用 django-debug-toolbar 之类的东西来掌握任何替代方案的时间。
我有两个模型:
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 %}
.....
问题是,有没有什么方法可以优化我的所有查询集,或者不可能 select 一次数据库调用有五个过滤器?
据我了解,如果我仅在视图中保存此调用 all_tasks = Task.objects.all()
,然后将逻辑放入模板中,如下所示:
{% for item in all_task %}
{% if item.status_id == "new" %}
....
也将有五次通话
希望我的问题不要太宽泛
只需按您视图中的状态对您的任务进行分组:
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 %}
一种可能性是更改您的 CHOICES
(其中的拼写错误)以映射到对排序有意义的内容,例如整数。
然后使用 orderby 执行单个查询,并在模板中使用 ifchanged
标签。
无论您尝试什么,都请注意不要掉进 Django 中实现 SQL 逻辑的陷阱,只是为了避免额外的查询。
无论如何,我建议您使用 django-debug-toolbar 之类的东西来掌握任何替代方案的时间。