Могу ли я уменьшить количество запросов при итерации объекта RelatedManager в шаблоне? - PullRequest
2 голосов
/ 12 марта 2011

Это гипотетически для простоты. В моем приложении Django есть модели для Kit, KitSku и Sku. Модель KitSku связывает Ску с Китом, а также предоставляет количество этого Ску в этом наборе. В шаблоне у меня что-то типа:

<!-- SELECT * FROM kitsku_table WHERE kit_id = <Kit.id> -->
{% for kitsku in kit.kitsku_set.all %}
  <!-- SELECT * FROM sku_table WHERE sku = <KitSku.sku> -->
  <div>{{ kitsku.sku.name }}</div>
{% endfor %}

Теперь проблема в том, что Django запрашивает все строки KitSku и затем запрашивает каждый sku внутри цикла for в отдельном запросе SQL для каждой итерации.

Могу ли я заставить SQL-запрос, полученный в результате вызова kitsku_set.all (), выполнить JOIN с моделью Sku?

Этот первый запрос должен быть похож на:

SELECT * FROM kitsku_table k LEFT JOIN sku_table s ON (k.sku = s.sku) 
WHERE k.kit_id = <Kit.id>

Ответы [ 2 ]

1 голос
/ 15 мая 2014

Я просто копирую ответ на похожий вопрос, но я думаю, что это гораздо лучший подход.

вид

newsletters = Newsletter.objects.prefetch_related('article_set').all()\
                    .order_by('-year', '-number')

return render_to_response('newsletter/newsletter_list.html',
                          {'newsletter_list': newsletters})

шаблон

{% block content %}
  {% for newsletter in newsletter_list %}
    <h2>{{ newsletter.label }}</h2>
    <p>Volume {{ newsletter.volume }}, Number {{ newsletter.number }}</p>
    <p>{{ newsletter.article }}</p>
    <ul>
    {% for a in newsletter.article_set.all %}
      <li>{{ a.title }}</li>
    {% endfor %}
    </ul>
  {% endfor %}
{% endblock %}

Вот полное объяснение: Надеется, что это поможет

Итерация по связанным объектам в Django: цикл по набору запросов или использование однострочного select_related (или prefetch_related)

1 голос
/ 12 марта 2011

Используйте этот тип логики в представлении и используйте select_related () для прямого запроса внешних ключей

kitskus = Kit.objects.get(id=3).kitsku_set.select_related('sku')
return direct_to_template(request, "mytemplate.html", {'kitskus': kitskus})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...