/ / Dans Django, existe-t-il un moyen simple de rendre un champ de texte en tant que modèle, dans un modèle? - django, modèles, filtre, tags

Dans Django, existe-t-il un moyen simple de rendre un champ de texte sous forme de modèle, dans un modèle? - Django, modèles, filtre, tags

Pouvez-vous imaginer un moyen simple d'évaluer un champ de texte en tant que modèle lors du rendu du modèle.

Je sais comment le faire dans une vue, mais je recherche un modèle de filtre ou un tag?

Quelque chose comme:

{{ object.textfield|evaluate}} ou {% evaluate object.textfield %}

avec object.textfield contenant quelque chose comme:

a text with a {% TemplateTag %}.

Dans lequel TemplateTag seront évalués, grâce à la evaluate filtre.

Réponses:

11 pour la réponse № 1

Voici une première implémentation de Tag pour résoudre ma question:

from django import template

register = template.Library()

@register.tag(name="evaluate")
def do_evaluate(parser, token):
"""
tag usage {% evaluate object.textfield %}
"""
try:
tag_name, variable = token.split_contents()
except ValueError:
raise template.TemplateSyntaxError, "%r tag requires a single argument" % token.contents.split()[0]
return EvaluateNode(variable)

class EvaluateNode(template.Node):
def __init__(self, variable):
self.variable = template.Variable(variable)

def render(self, context):
try:
content = self.variable.resolve(context)
t = template.Template(content)
return t.render(context)
except template.VariableDoesNotExist, template.TemplateSyntaxError:
return "Error rendering", self.variable

1 pour la réponse № 2

Cela va impliquer des expressions régulières. Quelque chose dans lequel je ne suis pas si doué, j'ai écrit un exemple mais vous (ou quelqu'un d'autre ici) aurez (je vous garantis) un moyen plus efficace de le faire. Mais ce n'est qu'un exemple:

from django.template import Library, Node, TemplateSyntaxError
from django.template import Template, Context

register = Library()

class TemplateEvalNode(Node):
def __init__(self, value):
self.value = Variable(value)

def render(self, context):
value = self.value.resolve(context)
regex = re.compile("{% w+ %}")
# Grab the template tag (eg. {% TemplateTag %})
unevaluated_var = regex.search(value)

if unevaluated_var == None:
return value

# Create a template containing only the template tag
t = Template(unevaluated_var)
# Evaluate that template (with context)
return_var = t.render(Context(context))

# Return the original value with the template tag replaced with
# its actual value
return value.replace(unevaluated_var, return_var)

def template_eval(parser, token):
bits = token.contents.split()
if len(bits) != 2:
raise TemplateSyntaxError, "template_eval takes exactly one argument"
return TemplateEvalNode(bits[1])

template_eval = register.tag(template_eval)

Je n'ai pas encore testé cela, donc cela peut ne pas fonctionner directement, mais en théorie, vous pouvez exécuter:

{% template_eval object.textfield %}

Et cela reviendrait:

a text with a VALUE_OF_TEMPLATETAG.

Attendez-vous à une mise à jour de ceci car je vais le tester maintenant et essayer de résoudre tous les problèmes, ma batterie est sur le point de mourir, donc je poste ceci maintenant non testé.

Attendez-vous également à une solution beaucoup plus intelligente de la part de quelqu'un qui est meilleur en Python que moi: p.

EDIT: OK, j'étais trop lent, tu m'as battu!