Работа с зависимыми объектами в шаблонах Django

#django #python-3.x

#django #python-3.x

Вопрос:

Прежде всего, правильно ли я понимаю, что теги Django сами по себе являются мини-языком и что Python не будет работать в них?

Если да, то как мне следует обращаться со значениями, которые было бы сложно предварительно обработать в представлении? Например, это то, что я хочу сделать (у пользователя много оценок):

 {% for user in users %} # Where users are defined in the view/context
  ...
{% endfor %}
  

Затем внутри этого я попробовал несколько вещей

   {% for rating in user.ratings %}
  

или

   {% for rating in Rating.objects.filter(user=user) %}
  

Первый никогда не повторяется. Последнее отвратительно и в любом случае не работает — оно вызывает TemplateSyntaxError at / Could not parse the remainder

Но поскольку я получаю соответствующего пользователя для фильтрации только в середине цикла между пользователями, я не уверен, как бы я настроил второй набор запросов в представлении.

Каков наилучший подход здесь?

Ответ №1:

Вы правы в том, что вы не можете запускать произвольный Python в шаблоне: синтаксис определяется системой шаблонов, которая по умолчанию является языком шаблонов Django (DTL).

В вашем конкретном случае есть простой способ получить доступ к связям внешнего ключа объекта модели: используйте _set ключевое слово. Должно работать следующее:

 {% for rating in user.rating_set.all %}
<!-- do stuff with rating -->
{% endfor %}
  

При поиске just item.ratings ожидается, что это будет ratings поле модели. Вам нужно указать _set , чтобы направить его на просмотр моделей внешнего ключа.

Этот случай прост: в других случаях лучшим вариантом является запуск логики в представлении и передача переменной в контекст шаблона или (нетривиально) создание собственного пользовательского тега шаблона.

Ответ №2:

Вам нужно использовать _set.all

 {% for user in users %} # Where users are defined in the view/context
    {% for rating in user.rating_set.all %}
        ...
    {% endfor %}
{% endfor %}
  

Если вам нужно фильтровать, посмотрите это.