Использовать переменную цикла как ключ словаря в шаблоне Django - PullRequest
5 голосов
/ 26 сентября 2011

Я пытаюсь заставить работать следующее.

Цикл подсчета должен проходить по всем значениям, и с каждым счетчиком может не быть пользователя, но значение счетчика i необходимо использовать в каждом цикле для передачи в JavaScript.

Python часть:

users = {}
users[1]={}
users[1][id]=...
users[1][email]=...

...

count=[1,2,3,4,5,6,7,8,9,10]

Часть шаблона Django:

{% for i in count %}
do some stuff with the value i using {{i}} which always returns the value, i.e. 1

email:{% if users.i.email %}'{{users.i.email}}'{% else %}null{% endif%}
{% endfor %}

Это ничего не возвращает для электронной почты. Когда я заменяю число 1 на i в {% if user.i.email %}, электронная почта возвращает адрес электронной почты пользователя. Я использую данные в JavaScript, поэтому они должны быть неявно нулевыми, если они не существуют. Я не могу заставить Django распознавать переменную i как переменную вместо значения i.

использование [] не работает, так как выдает неверную синтаксическую ошибку

email:{% if users.[i].email %}'{{users.[i].email}}'{% else %}null{% endif%}

Я пытался использовать выражение "with"

{% for i in count %}{% with current_user=users.i %}...

и затем с помощью current_user.email, но ничего не возвращалось

тоже пробовал

{% for i in count %}{% with j=i.value %}...

на всякий случай, если это сработает, а затем попытаться использовать j, но тот же результат.

Я думал о создании внутреннего цикла for, который зацикливается на объекте пользователя и проверяет, равен ли я ключу / значению, но это кажется дорогим и не очень масштабируемым.

Есть идеи, как заставить Django просматривать i как переменную и использовать ее значение в качестве индекса, или каким-либо другим способом обойти это?

Спасибо

Jayd

* Edit:

Я попробовал дополнительный цикл for, как предложено Абхи, ниже.

{% for i in count %}
  {% for key, current_user in users.items %}
      do some stuff with the value i using {{i}} which always returns the value, i.e. 1
      email:{% if i == key and current_user.email %}'{{current_user.email}}'{% else %}null{% endif%}
  {% endfor %}
{% endfor %}

Этот вид работает, но теперь он будет повторяться do some stuff with the value i для каждого значения пользователей. и если я вставлю в if:

{% for i in count %}
  {% for key, current_user in users.items %}
    {% if i == key %}
      do some stuff with the value i using {{i}} which always returns the value, i.e. 1
      email:{% if i == key and current_user.email %}'{{current_user.email}}'{% else %}null{% endif%}
    {% endif%}
  {% endfor %}
{% endfor %}

Это игнорирует циклы, когда у счетчика нет определенного пользователя.

Единственный способ, которым я могу видеть это, это иметь пользовательский цикл в каждом месте, которое я хочу использовать current_user.

{% for i in count %}
      do some stuff with the value i using {{i}} which always returns the value, i.e. 1
      email:{% for key, current_user in users.items %}{% if i == key and current_user.email %}'{{current_user.email}}'{% else %}null{% endif%}{% endfor %}
{% endfor %}

И это кажется очень дорогим. Есть идеи?

Я думал о том, чтобы написать фильтр, который возвращает значения для пользователей, используя i в качестве ключа:

{% with current_user=users|getuser:i %}

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

Я так долго попробую.

* Редактировать

Это не сработало. Фильтр работал, используя {{}}, возвращая объект, но он не работал внутри {% %} .

Спасибо за ввод

Ответы [ 4 ]

9 голосов
/ 26 сентября 2011

Как говорит Джо в своем комментарии, словарь явно является неправильной структурой данных для внешнего контейнера.Вы должны использовать список.

users = []
user = {'id':..., 'email': ...}
users.append(user)

...

{% for user in users %}
    {{ user.email }}
{% endfor %}

Если вам нужен номер каждого пользователя в цикле, вы можете использовать {{ forloop.counter }}.

1 голос
/ 11 января 2013

, чтобы Jayd Code можно было использовать с списком или диктом, попробуйте это

@register.filter(name='dict_value_or_null')
def dict_value_or_null(dict, key):
    try:
        return dict[key]
    except:
        return 'null'
1 голос
/ 27 сентября 2011

В качестве обходного пути я придумал следующее:

Это код фильтра:

@register.filter(name='dict_value_or_null')
def dict_value_or_null(dict, key):
    if key in dict:
        return dict[key]
    else:
        return 'null'

Вот код шаблона

{% for i in count %}
      do some stuff with the value i using {{i}} which always returns the value, i.e. 1
      email:'{{users|dict_value_or_null:i|dict_value_or_null:'email'}}'
{% endfor %}

Это хорошо работает, поэтому я полагаю, что у меня есть решение.Но я все еще думаю, что все это могло бы быть намного проще, если бы в системе шаблонов был способ заставить значения внутри {%%} обрабатываться как переменные, а не как литералы.

Есть ли способ сделатьэто?

Спасибо за ввод

1 голос
/ 26 сентября 2011

Попробуйте это:

{% for key,val in user.items %}
ID is {{ val.id }} and Email is {{ val.email }}
{% endfor %}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...