Considerar:
#!/usr/bin/env python3
from collections import OrderedDict
import jinja2
t = '''
{% for key, value in d.iteritems() %}
* {{ key }}: {{ value }}
{% endfor %}
'''
jt = jinja2.Template(t)
d = OrderedDict()
d['one'] = 1
d['two'] = 2
d['three'] = 3
print(jt.render(d=d))
Quando executado com Python 3, você obtém uma exceção confusa:
Traceback (most recent call last):
File "jinja2-OrderedDict.py", line 20, in <module>
print(jt.render(d=d))
File "/usr/lib/python3/dist-packages/jinja2/environment.py", line 895, in render
return self.environment.handle_exception(exc_info, True)
File "/usr/lib/python3/dist-packages/jinja2/environment.py", line 671, in handle_exception
raise exc_value.with_traceback(tb)
File "<template>", line 2, in <module>
jinja2.exceptions.UndefinedError: b"'collections.OrderedDict object' has no attribute 'iteritems'"
Isso ocorre porque o modelo usa iteritens, que são removidos do Python 3. A partir da exceção acima, não está claro se o problema está no modelo - deveria estar.
Funciona para dicionários normais do Python 3 porque as linhas 205–210 do Jinja2 v2.61 adicionam de volta um método de iteritens:
# not available on python 3
if hasattr(dict, 'iterkeys'):
iterkeys = _all('iterkeys')
itervalues = _all('itervalues')
iteritems = _all('iteritems')
del _all
Qual é a melhor maneira de consertar isso? Detectar melhor objetos do tipo dict, tentar cuspir um erro melhor, etc?
Os dicionários não têm métodos iteritem no 3.x. Você precisará mudar para .items()
. Nada que eu possa fazer sobre isso.
Seria bom se houvesse um filtro embutido para esta e outras esquisitices do python 2to3.
A menos que você tenha grandes dictos, usar .items()
não é / tão / ruim
Esta é uma maneira de contornar isso:
importar seis
env = jinja2.Environment(loader=jinja2.FileSystemLoader('your_dir'))
env.globals['six_iteritems'] = six.iteritems
template = env.get_template('your_template')
Então, em seu modelo:
usar:
{% para chave, valor em six_iteritems (sua var)%}
É meio feio, mas funciona.
usando .items () em vez de .iteritems () funcionou
Comentários muito úteis
Os dicionários não têm métodos iteritem no 3.x. Você precisará mudar para
.items()
. Nada que eu possa fazer sobre isso.