Рендеринг питона в Jinja2/Werkzeug
Я играю с сокращением url (основывая его на коротком демо-приложении от Werkzeug).
У меня есть такой диктофон -
('1', {'target': 'http://10.58.48.103:5000/', 'clicks': '1'})
('3', {'target': 'http://slash.org', 'clicks': '4'})
('2', {'target': 'http://10.58.48.58:5000/', 'clicks': '1'})
('5', {'target': 'http://de.com/a', 'clicks': '0'})
который возвращается в url_list и используется render_template
def on_list_urls(self, request):
url_list = self.get_urls()
return self.render_template('list_urls.html',
url_list = url_list
)
шаблон list_urls довольно прост -
{% extends "layout.html" %}
{% block title %}List URLs{% endblock %}
{% block body %}
<h2>List URLs</h2>
<ul id="items">
{% for item in url_list %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{% endblock %}
Дело в том, что я не могу получить доступ к элементам в dict.
Линия
<li>{{ item }}</li>
- это то место, где я фокусирую внимание. Как и выше, я получаю список ключей в dict.
<li>{{ item["target"] }}</li>
ничего не возвращает. Ни один из {{user.url}}" > {{user.username}}
тип файла в документах, похоже, работает.
Идеи, пожалуйста? Новичок - будьте осторожны. Спасибо.
Обновление
Спасибо за ответы.
Ответ ответа Ewan, но использует список dicts. Я хочу передать dict и сделать это (потому что мне нужен нецелый индекс элементов). Это делает Jinja?
Кроме того, я неправильно представил url_list. Это более похоже на это -
{'a': {'target': 'http://testing.com/test', 'clicks': '0'},
'1': {'target': 'http://10.58.48.103:5000/', 'clicks': '1'},
'3': {'target': 'http://slash.org', 'clicks': '4'},
'2': {'target': 'http://10.58.48.58:5000/', 'clicks': '1'}}
Дальнейшее экспериментирование - передача dict приводит к ошибке в отношении объекта списка.
{% for key in url_list.iteritems() %}
UndefinedError: 'list object' has no attribute 'iteritems'
Еще раз спасибо.
По-прежнему озадачен тем, почему он думал, что я передаю список, но теперь он работает.
{% for key, value in url_list.iteritems() %}
<li>{{ key }} - {{ value["target"] }} - {{ value["clicks"] }}</li>
распечатывает все. Большое спасибо.
Ответы
Ответ 1
Ваш url_list
должен выглядеть следующим образом:
url_list = [{'target': 'http://10.58.48.103:5000/', 'clicks': '1'},
{'target': 'http://slash.org', 'clicks': '4'},
{'target': 'http://10.58.48.58:5000/', 'clicks': '1'},
{'target': 'http://de.com/a', 'clicks': '0'}]
Затем, используя:
<li>{{ item["target"] }}</li>
в вашем шаблоне будет работать.
Изменить 1:
Ваш шаблон думает, что вы передаете список, так что вы уверены, что проходите в своем оригинальном dict, а не в моем списке?
Также вам нужно получить доступ к key
и value
в словаре (когда вы передаете словарь, а не список):
Python 2.7
{% for key, value in url_list.iteritems() %}
<li>{{ value["target"] }}</li>
{% endfor %}
Python 3
{% for key, value in url_list.items() %}
<li>{{ value["target"] }}</li>
{% endfor %}
Ответ 2
Обратите внимание, что dict.items()
существует как в Python 2, так и в Python 3. Но метод не дает никаких гарантий относительно того, что элементы заказа, содержащиеся в словаре, повторяются. Вот почему для этого примера может иметь смысл использовать список словарей вместо словаря словарей, как вы сказали выше.
Ответ 3
Одним из подходов является четкое отделение логики обработки от HTML. Таким образом, поместите HTML в отдельный файл, например, top.reddit.html
. Но контент в HTML динамический, так как он взят из Reddit. Поэтому мы используем Jinja2 в качестве движка шаблонов. Это подразумевает, что top.reddit.html
- это просто шаблон, но не конечный контент, который должен быть top.reddit.html
.
top.reddit.html (здесь показаны только динамические строки для краткости):
{% for item in data %}
<tr>
<td width="0%"> </td>
<td>{{item["date"]}}, {{item["title"]}}<br>{{item["teaser"]}}</td>
<td width="0%"> </td>
</tr>
{% endfor %}
Код Python для визуализации шаблона (протестировано с Python 3.5.6, Jinja2 2.10):
import jinja2
# For illustration: list of dict
top_posts = [
{'date': '06 Jun, 11:40AM', 'title': 'Title 1 goes here', 'teaser': 'One blah blah blah...'},
{'date': '05 Jun, 04:50PM', 'title': 'Title 2 goes here', 'teaser': 'Two blah blah blah...'},
{'date': '05 Jun, 09:60AM', 'title': 'Title 3 goes here', 'teaser': 'Three blah blah blah...'}
]
loader = jinja2.FileSystemLoader(searchpath="./")
jenv = jinja2.Environment(loader=loader)
template = jenv.get_template('top.reddit.html')
htmlout = template.render(data=top_posts)
print(htmlout)