【问题标题】:Django: variable in variable in templatesDjango:模板中的变量中的变量
【发布时间】: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 问题。问题已结束。

【问题讨论】:

    标签: python html django templates


    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2012-08-23
      • 2021-06-14
      • 1970-01-01
      • 1970-01-01
      • 2012-04-14
      • 2016-04-22
      相关资源
      最近更新 更多