Ho una soluzione, sto ordinamento di un oggetto dict:
registers = dict(
CMD = dict(
address = 0x00020,
name = 'command register'),
SR = dict(
address = 0x00010,
name = 'status register'),
)
ho voluto un loop all'interno di dict registro, ma ordina per indirizzo. Quindi avevo bisogno di un modo per ordinare dal campo 'indirizzo'. Per fare questo, ho creato un filtro personalizzato e passare l'espressione lambda come una stringa, allora io uso eval built-in di Python() per creare il vero lambda:
def my_dictsort(value, by='key', reverse = False):
if by == 'key':
sort_by = lambda x: x[0].lower() # assumes key is a str
elif by == 'value':
sort_by = lambda x: x[1]
else:
sort_by = eval(by) # assumes lambda string, you should error check
return sorted(value, key = sort_by, reverse = reverse)
Con questa funzione, è possibile iniettare nel Jinja2 ambiente in questo modo:
env = jinja2.Environment(...)
env.filters['my_dictsort'] = my_dictsort
env.globals['lookup'] = lookup # queries a database, returns dict
E poi chiamare dal tuo modello:
{% for key, value in lookup('registers') | my_dict_sort("lambda x:x[1]['address']") %}
{{"""\
static const unsigned int ADDR_{key} = 0x0{address:04X}; // {name}
""" | format(key = key, address = value['address'], name = value['name'])
}}
{% endfor %}
uscita:
static const unsigned int ADDR_SR = 0x00010; // status register
static const unsigned int ADDR_CMD = 0x00020; // command register
Quindi puoi passare una lambda come stringa, ma dovrai aggiungere un filtro personalizzato per farlo.
Per favore, non usare mai la logica complessa nei modelli. Non sono progettati per questo. Dovresti considerare come modelli leggeri il più possibile con la maggior parte delle operazioni logiche sul back-end. Immagina cosa diresti dopo aver trovato qualcosa di simile dopo un altro sviluppatore? Considera [buildin filters] (http://jinja.pocoo.org/docs/templates/#builtin-filters). 'Lambda' crea una funzione anonima che è molto più difficile da eseguire il debug. – boldnik
Puoi suggerire un modo per fare ciò che voglio usando i filtri integrati? (cioè ho una lista di oggetti e ho bisogno di accedere a un attributo di un figlio di ciascuno degli oggetti?) Non penso che quello che sto cercando di fare sia davvero più complicato in senso logico di quello che è stato costruito in "mappa" lo consente, ma non penso di poter fare ciò che voglio con la mappa integrata. Per favore, mostrami se posso! – Lee
La domanda è "lambda come argomento del filtro jinja2?" E la risposta è "No, non è possibile passare un'espressione generale Python per filtrare nel modello Jinja2". Sembra essere corretto Ora, se si desidera utilizzare un filtro personalizzato su un elenco di oggetti nel modello, la domanda è "perché".Perché non filtrare gli oggetti * prima * passando l'elenco al modello? Perché è necessario filtrare * dopo * passarlo al modello? – boldnik