web-dev-qa-db-fra.com

Comment définir une valeur de variable dans un code de modèle?

Dis que j'ai un modèle

<html>
<div>Hello {{name}}!</div>
</html>

Lors du test, il serait utile de définir la valeur de la variable sans toucher au code python qui appelle ce modèle. Donc je cherche quelque chose comme ça

{% set name="World" %}     
<html>
<div>Hello {{name}}!</div>
</html>

Est-ce que quelque chose comme ça existe à Django?

186
Alexis

Vous pouvez utiliser la balise de modèle with .

{% with name="World" %}     
<html>
<div>Hello {{name}}!</div>
</html>
{% endwith %}
286
John

Une autre manière de ne pas obliger à tout mettre dans le bloc "with" consiste à créer une balise personnalisée qui ajoute une nouvelle variable au contexte. Un péché:

class SetVarNode(template.Node):
    def __init__(self, new_val, var_name):
        self.new_val = new_val
        self.var_name = var_name
    def render(self, context):
        context[self.var_name] = self.new_val
        return ''

import re
@register.tag
def setvar(parser,token):
    # This version uses a regular expression to parse tag contents.
    try:
        # Splitting by None == splitting by spaces.
        tag_name, arg = token.contents.split(None, 1)
    except ValueError:
        raise template.TemplateSyntaxError, "%r tag requires arguments" % token.contents.split()[0]
    m = re.search(r'(.*?) as (\w+)', arg)
    if not m:
        raise template.TemplateSyntaxError, "%r tag had invalid arguments" % tag_name
    new_val, var_name = m.groups()
    if not (new_val[0] == new_val[-1] and new_val[0] in ('"', "'")):
        raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
    return SetVarNode(new_val[1:-1], var_name)

Cela vous permettra d’écrire quelque chose comme ceci dans votre modèle:

{% setvar "a string" as new_template_var %}

Notez que la plupart de ceci était pris d'ici

30
Karim

Créez une balise de modèle:

L'application doit contenir un répertoire templatetags, au même niveau que models.py, views.py, etc. S'il n'existe pas encore, créez-le. N'oubliez pas le __init__.py fichier pour s'assurer que le répertoire est traité comme un package Python.

Créez un fichier nommé define_action.py à l'intérieur du répertoire templatetags avec le code suivant:

from Django import template
register = template.Library()

@register.assignment_tag
def define(val=None):
  return val

Remarque: Le serveur de développement ne redémarre pas automatiquement. Après avoir ajouté le module templatetags, vous devez redémarrer votre serveur avant de pouvoir utiliser les balises ou les filtres dans les modèles.


Ensuite, dans votre modèle, vous pouvez affecter des valeurs au contexte comme ceci:

{% load define_action %}
{% if item %}

   {% define "Edit" as action %}

{% else %}

   {% define "Create" as action %}

{% endif %}


Would you like to {{action}} this item?
28
Mods Vs Rockers

Il y a des astuces comme celle décrite par John; Cependant, le langage de template de Django par conception ne supporte pas la définition d'une variable (voir l'encadré "Philosophie" dans documentation Django pour les templates ).
Pour cette raison, la méthode recommandée pour modifier une variable est en touchant le code Python.

23
rob

La meilleure solution est d'écrire un assignment_tag personnalisé. Cette solution est plus propre que l’utilisation d’une balise with car elle établit une séparation très claire entre la logique et le style.

Commencez par créer un fichier de balise de modèle (par exemple, appname/templatetags/hello_world.py):

from Django import template

register = template.Library()

@register.assignment_tag
def get_addressee():
    return "World"

Vous pouvez maintenant utiliser la balise de modèle get_addressee dans vos modèles:

{% load hello_world %}

{% get_addressee as addressee %}

<html>
    <body>
        <h1>hello {{addressee}}</h1>
    </body>
</html>
10
unique entity

Peut-être que le default filtre de modèle n'était pas une option en 2009 ...

<html>
<div>Hello {{name|default:"World"}}!</div>
</html>
4
John Mee

Ce n'est pas une bonne idée en général. Faites toute la logique dans python et transmettez les données au modèle pour l'affichage. Le modèle doit être aussi simple que possible pour que les personnes travaillant sur la conception puissent se concentrer sur la conception plutôt que de se préoccuper de la logique.

Pour donner un exemple, si vous avez besoin d’informations dérivées dans un modèle, il est préférable de les insérer dans une variable du code python, puis de les transmettre au modèle.

3
Sarang

Utilisez le avec déclaration .

{% with total=business.employees.count %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}

Je ne peux pas impliquer le code dans le premier paragraphe de cette réponse . Peut-être que le langage de template avait obsolète l'ancien format.

2
ramwin

Dans votre modèle, vous pouvez faire comme ceci:

{% jump_link as name %}
{% for obj in name %}
    <div>{{obj.helo}} - {{obj.how}}</div>
{% endfor %}

Dans vos templates-tags, vous pouvez ajouter un tag comme ceci:

@register.assignment_tag
def jump_link():
    listArr = []
    for i in range(5):
        listArr.append({"helo" : i,"how" : i})
    return listArr
1
Ashish Gupta