Django:模板中变量的变量

时间:2015-10-14 11:47:34

标签: python html django templates

让我们假设以下情况。在我的数据库(模型)中,我有一个为学生描述任务的领域。每个学生都应该在任务中拥有自己的一些变量变体。因此,我在数据库中保存了名为task的以下模型:

 id | name    | description                                  |
 ---+---------+----------------------------------------------+
  1 | Simple  | This is first task. Answer is {{student_var}}|

视图的方法很简单(TeamFlag是一个关联团队和任务的表:

def render_team(request, team):
    tasks = TeamFlag.objects.filter(team=team)
    return render(request,
                  'team.html',
                  dict({'team': team,
                        'tasks': tasks,
                        'student_var': 'foo',
                        }))

在我的模板中:

{% for team_task in tasks %}
    <li class="item">
        <h6>{{ team_task.task.name }}</h6>
        <div class="task-content">{% autoescape off %}
                                  {{team_task.task.description }}
                                  {% endautoescape %}</div>

结果我看到了:

 This is first task. Answer is {{student_var}}

Django中是否有任何方法可以预处理变量,这些变量位于字符串内部并将处理后的HTML字符串传递给模板内部的视图,基于变量(我计划将数据保存在KV格式的数据库中,带有字段例如:idkeyvalueteam_idtask_id)。

通常,我希望有一些方法,如process_template(html_string, kv-data),它返回已处理的HTML字符串或类似的东西。我听说过模板的自定义过滤器,但我不确定,是不是这样。

UPD:我成功添加了以下代码:

tasks = TeamFlag.objects.filter(team=team)
for tf in tasks:
    data = TaskData.objects.filter(team=team, task=tf.task)
    tf.task.description = Template(tf.task.description).render(
        Context(dict(zip([x.key for x in data],
                         [x.value for x in data]))))

但是,Django现在忽略了tf.task.description中的布局。我的新描述如下:

I have some {{temp}} <b>here</b> and it's {{temp2}}

它正在呈现,我可以在页面的源代码中看到它,但实际上没有任何反应。

UPD2:似乎是CSS问题。问题已经结束。

3 个答案:

答案 0 :(得分:3)

对于辅助方法,您可以创建包含TemplateContext

的内容
from django.template import Template, Context

def process_template(tasks, student_var):
    new_tasks = []
    for team_task in tasks:
        template = Template(team_task.task.description)
        context = Context({'student_var': student_var})
        rendered_template = template.render(context)
        team_task.task.description = rendered_template
        new_tasks.append(team_task)
    return new_tasks

def render_team(request, team):
    tasks = process_template(TeamFlag.objects.filter(team=team))

您可以查看documentation了解详情。

答案 1 :(得分:1)

模板处理器只是代码。它接受一个字符串,对其进行解析,并根据给定的上下文填充它。字符串可以像从磁盘上的文件一样轻松地来自数据库。

从根本上说它很简单:

from django.template import Template, Context

tpl = Template(task.description)
output = tpl.render(tpl, Context({'student_var': 'foo'}))

你把它放在哪里取决于你。它可以是模型方法,也可以是模板过滤器。你不回答的一个问题是变量的来源;如果只有student_var,您可以明确地将其传递给过滤器;如果不是,你必须找出从哪里获取它们。

答案 2 :(得分:1)

您可以创建一个简单的标记,并在django模板中使用它,如下所示:

{%my_custom_filter team_task.task.description%}

from django.template import Context, Template

@register.simple_tag(name='my_custom_filter', takes_context=True)
def my_custom_filter(context, val):
    template = Template(val)
    context = Context(context)
    final_val = template.render(context)
    return final_val