Modelos Django e atributos variáveis
-
09-06-2019 - |
Pergunta
Estou usando modelos do Google App Engine e Django.
Eu tenho uma tabela que desejo exibir os objetos parecidos com:
Object Result:
Items = [item1,item2]
Users = [{name='username',item1=3,item2=4},..]
O modelo do Django é:
<table>
<tr align="center">
<th>user</th>
{% for item in result.items %}
<th>{{item}}</th>
{% endfor %}
</tr>
{% for user in result.users %}
<tr align="center">
<td>{{user.name}}</td>
{% for item in result.items %}
<td>{{ user.item }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
Agora o Documentação Django afirma que quando vê um . em variáveis
Ele tenta várias coisas para obter os dados, uma das quais é a pesquisa no dicionário, que é exatamente o que eu quero, mas parece que não acontece ...
Solução
Encontrei uma solução "melhor"/"melhor" para obter variáveis dentro de não é a maneira mais legal, mas funciona.
Você instala um filtro personalizado no Django que obtém a chave do seu dict como parâmetro
Para fazê-lo funcionar no Google App-Engine, você precisa adicionar um arquivo ao seu diretório principal, liguei para o meu django_hack.py que contém este pequeno pedaço de código
from google.appengine.ext import webapp
register = webapp.template.create_template_register()
def hash(h,key):
if key in h:
return h[key]
else:
return None
register.filter(hash)
Agora que temos esse arquivo, tudo o que precisamos fazer é dizer ao app-engine para usá-lo...fazemos isso adicionando esta pequena linha ao seu arquivo principal
webapp.template.register_template_library('django_hack')
e na sua visualização de modelo adicione este modelo em vez do código normal
{{ user|hash:item }}
E deve funcionar perfeitamente =)
Outras dicas
Estou assumindo que a parte que não funciona é {{ user.item }}
.
Django tentará uma pesquisa no dicionário, mas usando a string "item"
e não o valor do item
variável de loop.Django fez a mesma coisa quando resolveu {{ user.name }}
para o name
atributo do user
objeto, em vez de procurar por uma variável chamada name
.
Acho que você precisará fazer algum pré-processamento dos dados em sua visualização antes de renderizá-los em seu modelo.
Ou você pode usar o sistema Django padrão que é usado para resolver atributos em tempaltes como este:
from django.template import Variable, VariableDoesNotExist
@register.filter
def hash(object, attr):
pseudo_context = { 'object' : object }
try:
value = Variable('object.%s' % attr).resolve(pseudo_context)
except VariableDoesNotExist:
value = None
return value
Isso simplesmente funciona
no seu modelo:
{{ user|hash:item }}
@Dave Webb (ainda não fui avaliado o suficiente para comentar)
As pesquisas de pontos podem ser resumidas assim:quando o sistema de templates encontra um ponto no nome de uma variável, ele tenta as seguintes pesquisas, nesta ordem:
* Dictionary lookup (e.e., foo["bar"])
* Attribute lookup (e.g., foo.bar)
* Method call (e.g., foo.bar())
* List-index lookup (e.g., foo[bar])
O sistema usa o primeiro tipo de pesquisa que funciona.É lógica de curto-circuito.
Como um substituto para k,v em user.items no Google App Engine usando modelos Django onde user = {'a':1, 'b', 2, 'c', 3}
{% for pair in user.items %}
{% for keyval in pair %} {{ keyval }}{% endfor %}<br>
{% endfor %}
um 1
b2
c3
par = (chave, valor) para cada item do dicionário.
não deveria isso:
{{ user.item }}
ser isso?
{{ item }}
não há objeto de usuário no contexto desse loop....?