2009-12-24 4 views
0

J'essaie de rendre le résultat d'une balise de gabarit dépendant d'un autre balise de gabarit. le cas d'utilisation est le suivant. J'ai une liste d'en-têtes qui contient toutes les colonnes que je veux montrer dans un tableau + la colonne du modèle qu'ils montrent + qu'ils soient visibles ou non.Modèle django templatetags, combiner {{}} appel de méthode avec une variable de contexte de balise de gabarit

LIST_HEADERS = (
    ('Title', 'title', True), 
    ('First Name', 'first_name', True), 
    ('Last Name', 'last_name', True), 
    ('Modified At', 'modified', False), 
) 

maintenant j'ai un modèle qui imprime tous les en-têtes. par conséquent, je voulais créer une étiquette de modèle qui imprime le corps de la table. par conséquent, je veux prendre la liste des en-têtes et vérifier quel en-tête est visible et que je veux afficher ou masquer ma valeur.

donc je créé le modèle de templatetag ci-dessous:

<tr class="{% cycle odd,even %}"> 
    {% for header in headers %} 
    {% if header.visible %} 
    <td><a href="{{ model_instance.get_absolute_url|escape }}">{{ model_instance.title }}</a></td> 
    {% else %} 
    <td style="visibility:hidden;"><a href="{{ model_instance.get_absolute_url|escape }}">{{ model_instance.title }}</a></td> 
    {% endif %} 
    {% endfor %} 
</tr> 

vous voyez la valeur {{}} model_instance.title là. cette valeur que je veux changer en model_instance.title, model_instance.first_name, model_instance.last_name, ... à l'exécution.

Ainsi, je cherche un moyen de combiner {{model_instance}} avec header.model_column. La colonne model_column est égale à la deuxième entrée des LIST_HEADERS.

Ainsi model_column serait un titre, prenom, ..

donc la solution serait quelque chose comme [pseudocode] {{model_instance.header.model_column}} [pseudocode]

..thus je recherche une manière dont je peux combiner un appel de méthode de modèle de django avec un attribut de balise de modèle de django..huh .. semble fou: D

J'espère que je l'ai expliqué assez bon! il y a probablement une solution beaucoup plus facile à mon problème. mais cela me semble assez générique et facile et ça marcherait.

Répondre

2

Je le ferais comme un filtre, car ils fournissent un moyen facile de rendre un résultat dépendant de la valeur d'une variable.

@register.filter 
def field_from_name(instance, field_name): 
    return getattr(instance, field_name, None) 

puis dans le modèle:

{{ model_instance|field_from_name:header.model_column }} 
+0

merci. Je pense que je vais essayer! semble bon et facile. –

2

simplifier. Tout d'abord, lisez les choses que le langage de modèle Django peut faire. Ce n'est pas beaucoup. Il peut déférer des variables, des listes et des dictionnaires.

C'est plus simple si vous faites tout le "travail" dans votre fonction de vue.

show = [ ] 
for title, field_name, visible in LIST_HEADERS: 
    if visible: style= "visibility:hidden" 
    else: style= "" 
    show.append((style, title, getattr(object,field_name)) 
render_to_response("template", { 'show_list': show, ... }, ...) 

Dans votre modèle

{% for style, name, value in show_list %} 
<tr class="{% cycle odd,even %}"> 
    <td class="{{style}}"><a href="...">{{value}}</a></td> 
{% endfor %} 

En effet, je vous suggère de laisser tomber LIST_HEADERS de votre fonction de vue. Je trouve ce qui précède beaucoup plus facile à travailler parce que c'est explicite et c'est dans la fonction de vue.

+0

+1 pour en faire plus dans la vue, moins dans le modèle. Cela rendra tout plus lisible. – cethegeek

+0

wow .. impressionnant. si vite .. et j'ai appris beaucoup de votre message. –

Questions connexes