2009-12-18 3 views
5

Selon The Django Book, le système de templating de Django prend en charge de points imbriqués lookups:dot lookups dans Django emboîtées templates

Dot peuvent être lookups imbriquées plusieurs niveaux de profondeur. Par exemple, l'exemple suivant utilise {{person.name.upper}}, qui se traduit par une recherche de dictionnaire (person ['nom']), puis un appel de méthode (upper()): '{{person.name.upper }} est {{person.age}} ans. '

Y a-t-il des gobelins avec cette approche qui n'est pas largement couverte dans la documentation? Je rencontre des problèmes avec des points imbriqués lookups - voici un exemple minimal:

views.py:

test = [{'foo': [1, 2, 3], 'bar': [4, 5, 6]}, {'baz': [7, 8, 9]}] 
ndx = 'bar' 
t = loader.get_template('meh.html') 
c = Context({'test': test, 
      'ndx': ndx,}) 
return HttpResponse(t.render(c)) 

modèle meh.html:

<pre> 
    {{ test }} 
    {{ test.0 }} 
    {{ test.0.ndx }} 
</pre> 

résultant HTML:

<pre> 
[{'foo': [1, 2, 3], 'bar': [4, 5, 6]}, {'baz': [7, 8, 9]}] 
{'foo': [1, 2, 3], 'bar': [4, 5, 6]} 

</pre> 

La recherche imbriquée d'une clé de dictionnaire dans un élément de liste ne renvoie rien, quand j'attends [4, 5, 6].

J.J.

+0

En tant que Goblin, je suis profondément insultée par cette d'une course entière ... ;-) – cethegeek

Répondre

8

Je pense que le problème est que vous attendez ndx à évaluer quand cela se produit tout simplement jamais. Avez-vous essayé ceci:

{{ test.0.bar }} 

Je pense que cela fera ce que vous cherchez.

Y a-t-il des gobelins avec cette approche ...?

Trier de, mais ils ne sont pas ceux dont vous parlez, et je ne pense pas que ce soit à cause de l'imbrication, ou tout au moins, qu'il ne soit pas pire après avoir obtenu un niveau de profondeur. Ce que je veux dire par là, c'est que tous les paramètres de recherche sont des littéraux. Il n'y a aucun moyen de changer cela. Ainsi, même si vous pouvez développer des balises de gabarit personnalisées et leur transmettre des littéraux ou des variables à évaluer, vous n'avez vraiment pas de chance si vous souhaitez accéder directement à un membre d'une variable en fonction de la valeur évaluée d'une autre valeur. (Vous pourriez éventuellement écrire une balise de gabarit pour cela, mais cela ne fonctionnera pas dans toutes les situations désirées et est peut-être plus compliqué que ça en vaut la peine.)

Pour quoi que ça vaille, cela ressemble à une facette assez intentionnelle du gabarit la langue. Je vous invite à considérer comment l'accesseur devrait savoir si {{ foo.bar }} devrait être lu comme foo[bar] ou foo['bar']. Il ne semble pas possible de faire un jugement sensé sans compliquer la syntaxe et c'est quelque chose que le modèle de django est catégorique à éviter.

+2

Merci d'avoir répondu à la question que j'aurais dû poser. :-) –

1

David a raison: ndx ne sera pas évalué pour obtenir une clé, il sera utilisé littéralement comme une clé. Vous pouvez définir une nouvelle balise de template pour faire ce que vous voulez, en voici une simple: http://www.djangosnippets.org/snippets/1412/

4

Pour développer la réponse de David, le système de template de Django ne vous permet pas d'utiliser la valeur d'une variable de contexte en tant que clé.Ainsi, dans votre exemple

{{ test.0.ndx }} 

est actuellement à la recherche de la "ndx" clé dans le premier élément de la variable de contexte test.

Si vous avez besoin de cette fonctionnalité, vous devez l'implémenter vous-même, en tant que filtre de gabarit. This ticket a plus d'informations, y compris le raisonnement de Django devs derrière l'omission de cette fonctionnalité et un exemple d'implémentation du filtre de gabarit que vous recherchez.

1

Je vous suggère soit (et je suis d'accord avec l'interprétation de David de votre problème):

{{ test.0.bar }} # as david mentioned, or 

ndx=test[0]['bar'] # in views 
{{ ndx }} # in template