Django Переоценка переменных в шаблоне

Допустим, в своих моделях я использую:

def Model1(models.Model):
   model2 = models.ForeignKey(Model2)

def Model2(models.Model):
   model3 = models.ForeignKey(Model3)

def Model3(models.Model):
   code1 = models.CharField(max_length=150)
   code2 = models.CharField(max_length=150)
   code3 = models.CharField(max_length=150)
   code4 = models.CharField(max_length=150)
   code5 = models.CharField(max_length=150)
   code6 = models.CharField(max_length=150)
   code7 = models.CharField(max_length=150)

А в шаблоне:

<td> {{ model1.model2.model3.code1 }} </td>
<td> {{ model1.model2.model3.code2 }} </td>
<td> {{ model1.model2.model3.code3 }} </td>
<td> {{ model1.model2.model3.code4 }} </td>
<td> {{ model1.model2.model3.code5 }} </td>
<td> {{ model1.model2.model3.code6 }} </td>
<td> {{ model1.model2.model3.code7 }} </td>

и для сравнения:

{% with col=model1.model2.model3 %}
   <td> {{ col.code1 }} </td>
   <td> {{ col.code2 }} </td>
   <td> {{ col.code3 }} </td>
   <td> {{ col.code4 }} </td>
   <td> {{ col.code5 }} </td>
   <td> {{ col.code6 }} </td>
   <td> {{ col.code7 }} </td>
{% endwith %}

В представлении я не использую select_related.

Мои вопросы следующие:

  1. Для первого кода означает ли это, что model1.model2.model3 будет запрошен Django 7 раз?
  2. Для второго кода, может ли использование with col=model1.model2.model3 ускорить отрисовку шаблона, так как запрос model1.model2.model3 осуществляется только один раз из блока {% with %}, и только получение переменных из col?
  3. Есть ли альтернативы обоим этим подходам?

В настоящее время моя SQL-таблица состоит из менее чем 1000 строк, поэтому проблемы с производительностью могут быть не видны. Но меня беспокоит вопрос, когда SQL-таблица будет достаточно большой и потребуется много оптимизации запроса.

  1. Да, Если вы не кэшируете результат запроса или любой другой пользовательский менеджер или ..., Django ORM будет выполнять вопрос каждый раз, когда вы его вызываете, для получения дополнительной информации об этом вы можете прочитать "When QuerySets are evaluated" в официальной документации.
  2. Это лучший способ, чем первый, потому что, как вы сказали, вы обращаетесь к базе данных только один раз и сохраняете результат, чтобы использовать его снова и снова.
  3. Зависит от того, что вы хотите сделать, если это не должно быть в реальном времени, вы можете использовать кэш, или вы можете написать функцию в model1 и вернуть то, что вы хотите от этой функции, затем вы можете сделать больше в ней (учитывая документацию, которую я упоминал ранее, чтобы сделать то, что вы хотите только в одном запросе)
Вернуться на верх