Теги шаблонов Django и метапрограммирование: есть ли способ изменить имя переменной перед вызовом ее контекста? - PullRequest
0 голосов
/ 06 января 2019

Предположим, в views.py у меня есть переменная (т.е. меняющаяся) количество форм или типов объектов в моем контексте. (Я просто буду использовать слово «формы» для простоты).

context = {
     'form_0': form_0,
     'form_1': form_1,
     'form_2': form_2,
     'form_3': form_3,
     # ... and so forth
}

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

{% for i in (number of forms in context) %}

{{ form_i }} <-- where i is equal to the number i in the loop -->

{% endfor %}

Здесь конечный результат будет переведен в:

{{ form_0 }}
{{ form_1 }}
{{ form_2 }}
... and so forth

Я сомневаюсь, что это вообще возможно, но если это так, я бы нашел это весьма полезным.

1 Ответ

0 голосов
/ 06 января 2019

Ссылка по имени, как и при построении строки, содержащей имя, обычно считается небезопасным подходом: может быть сложнее, чем кажется, создать алгоритм, который правильно создает имя. Более того, скажите, что вы делаете это, а затем удаляете form_3, тогда ваш алгоритм, скорее всего, остановится на 2, но, возможно, есть еще другие формы, но вы забыли об алгоритме извлечения форм.

Здесь лучше передать коллекцию объектов, например список :

context = {
    <b>'forms'</b>: <b>[</b>form_0, form_1, form_2, form_3<b>]</b>
}

тогда мы можем отобразить это в шаблоне с помощью:

{% for form_i in <b>forms</b> %}
    {{ form_i }}
{% endfor %}

Если вы, таким образом, добавите дополнительную форму в список, то эта форма будет частью итераций в шаблоне, и, таким образом, Django отобразит эту форму (или что-то, что вы добавили в список).

Если вам также необходим доступ к некоторым конкретным формам, вы можете передать и другое имя, например:

context = {
    'forms': [form_0, form_1, form_2, form_3],
    # if we need specific items of form_2 in the template,
    # we can pass it under a specific name as well
    'form_2': form_2
}

, поэтому теперь мы можем оба перечислить по forms для их рендеринга, но если у form_2 есть некоторые интересные данные, которые нам также необходимо обработать в шаблоне, мы все равно можем использовать, например, {{ form_2.non_field_errors }}.

...