Django:模板中的变量中的变量

Posted

技术标签:

【中文标题】Django:模板中的变量中的变量【英文标题】:Django: variable in variable in templates 【发布时间】:2016-01-12 11:46:14 【问题描述】:

让我们假设以下情况。在我的数据库(模型)中,我有一个描述学生任务的字段。每个学生在任务中都应该有自己的一些变量的变体。所以,我在数据库中保存了以下名为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 &lt;b&gt;here&lt;/b&gt; and it's temp2

它正在渲染,我可以在页面的源代码中看到它,但实际上什么也没发生。

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

【问题讨论】:

【参考方案1】:

对于辅助方法,您可以使用 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 了解更多信息。

【讨论】:

我更新了模型中的字段,但没有保存它们,因此数据库中没有任何变化,尽管更新的模型已正确传递给模板:for tf in tasks: template = Template(tf.task.description) context = Context('temp': '123') tf.task.description = template.render(context)【参考方案2】:

模板处理器只是代码。它接受一个字符串,解析它,并根据给定的上下文填充它。字符串既可以来自数据库,也可以来自磁盘上的文件。

从根本上讲,它很简单:

from django.template import Template, Context

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

你把它放在哪里取决于你。它可以是模型方法,也可以是模板过滤器。您没有回答的一个问题是变量的来源;如果只有student_var,您可以将其显式传递给过滤器;如果没有,您将不得不弄清楚从哪里获得它们。

【讨论】:

所有student_var-like 变量将来自数据库和相应的模型。那字符串呢,它也来自模型?我也只需要把它放到Context 中? 我不明白你在问什么。什么字符串? task.description 字符串 但是我没有在答案中表明这一点吗?您将其传递给模板实例化,它不是上下文的一部分。 好的,我会尝试并报告我的结果。我只是不想自己做渲染【参考方案3】:

您可以创建一个简单的标签并在 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

【讨论】:

以上是关于Django:模板中的变量中的变量的主要内容,如果未能解决你的问题,请参考以下文章

如何更新 django 模板中的渲染变量?

Django:访问子模板中的循环变量

有没有办法将变量传递给 Django 中的“扩展”模板?

如何使用Django模板在javascript中访问ajax jquery中的模板变量

如何将 django 变量正确转换为模板中的 json

Django模板表单中的变量“名称”