2016-01-26 3 views
2

У меня есть две модели:Django. Как я могу оптимизировать db-запрос?

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 %} 
.....  

Вопрос заключается в том, есть ли способ, чтобы оптимизировать все мои запросов или невозможно выбрать пять фильтров для одного вызова db?
Как я понимаю, если я сохранить в виде только этот вызов all_tasks = Task.objects.all(), а затем положить логику в шаблоне, например:

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

будет exaclty пяти звонков слишком
Надеются, что мой вопрос не является слишком широким

ответ

4

Просто группировать задачи по статусу, по вашему мнению:

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 %} 
+0

большой! Спасибо. Может быть, это глупый вопрос, но как я могу теперь получить объекты задачи в шаблоне? Мне не нужен список заказов с объектами один за другим. Мне нужно поместить объекты в пять столбцов для каждого состояния, например, в trello.com, поэтому мне нужно некоторое условие. Если я использую тег '{% if%}' для имени статуса проверки, это будет вызов db в любом случае? –

+1

Queryset должен быть 'Task.objects.select_related ('status'). Order_by ('status')'. В этом случае дополнительных запросов db не будет. – vsd

+0

@AlexMorozov благодарит много! –

2

Возможность изменить ваш CHOICES (опечатка там), чтобы сопоставить то, что имеет смысл в заказе, например целые числа.

Затем выполните один запрос с orderby и в шаблоне используйте тег ifchanged.

За что бы вы ни старались, будьте осторожны, чтобы не попасть в ловушку реализации SQL-логики в Django, чтобы избежать дополнительного запроса.

В любом случае, я бы порекомендовал вам использовать что-то вроде django-debug-toolbar, чтобы получить представление о времени для любой альтернативы.

Смежные вопросы