【问题标题】:Template loading and rendering outside of Django在 Django 之外加载和渲染模板
【发布时间】:2012-04-04 20:06:55
【问题描述】:

使用this guide as my reference,我为一个适用于 TWIG 的集合语法的 Django 模板编写了一个集合标记解析器,即:

{% set someVar %} variableAssignment {% endset %}

我只将 Django 用于它的模板系统,直到此时我已经能够通过正确的导入来正确显示我的模板。这是我目前的代码:

from django.template import Context, Template, Library, Node, TemplateSyntaxError, Variable, VariableDoesNotExist, resolve_variable
from django.template.loader import *
from django.conf import settings
settings.configure(TEMPLATE_DIRS="/my/templates")
register = Library()
class SetValueNode(Node):
    def __init__(self, variable, nodelist):
        self.variable = variable
        self.nodelist = nodelist
    def render(self, context):
        context[self.variable] = self.nodelist.render(context)
        return ""

@register.tag(name="set")
def set_tag(parser, token):
    print "set_tag called: parser",parser," token",token
    nodelist = parser.parse(("endset",))
    parser.delete_first_token()
    return SetValueNode(arg, nodelist)

def sendServiceEmail(username, first, last, service, service_tuple):
    TEMPLATES_DIR = "/my/templates/"
    emailStr = "myemail.html.twig"
    print "Opening file :"+TEMPLATES_DIR+emailStr
    t = Template(fp.read())
    fp.close()
    c = Context({
            /*Add context from parameters*/
        })
    msg = t.render(c)
    print msg

但我得到的错误是:

django.template.base.TemplateSyntaxError: 'set_tag' is not a valid tag library: Template library set_tag not found, tried django.templatetags.set_tag

经过一番研究和思考,django 正在寻找的库似乎是“标准”库。我认为我需要告诉某人(django 设置、模板或 .render)我希望他们使用“库”并检查库以查看模板标签是否已注册。有什么方法可以在不创建 django 应用的情况下将这些信息传递给 Django?

【问题讨论】:

  • 这段代码在哪里?你是怎么加载它的?
  • 这段代码位于一个独立的脚本中,由守护进程运行。这个想法是在发送给用户之前使用 Django 中的模板结构来格式化电子邮件。它通过调用加载:sendServiceEmail("testUser","Ima","TestUser","Some Service", ("other stuff",))

标签: django django-templates


【解决方案1】:

以下信息适用于 Django 1.4 你有三个选择。

应用解决方案

您需要创建一个具有定义结构的应用程序,但它不必是一个完整的 django 应用程序。假设你叫它myapp

这是强制性的文件结构

myapp/
  __init__.py
  templatetags/
    __init__.py
    your_library.py

在您的主脚本中执行以下操作

from django.conf import settings
from django.template.loader import get_template

# You need to configure Django a bit
settings.configure(
    # Access to template tags
    INSTALLED_APPS=('myapp', ),
    # Access to templates
    TEMPLATE_DIRS=(TEMPLATES_DIR, ),
)

template = get_template("myemail.html.twig")
# Prepare context ....
return t.render(context)

一个模块解决方案

如果你不愿意使用这么大的结构,应该可以只创建一个带有模板标签的模块并将其传递给django.template.base.add_to_builtins方法,见https://github.com/django/django/blob/master/django/template/base.py#L1349

完全不同的东西

或者你可以考虑使用 jinja2 http://jinja.pocoo.org/docs/ 代替,但我不知道标签在那里工作。

【讨论】:

    【解决方案2】:

    感谢@zimma 的精彩提示。我想提供一个模块加载选项的完整示例。

    假设你有这个重要的模板标签要从 read.py 添加

    from django import template
    
    register = template.Library()
    
    @register.filter(name='bracewrap')
    def bracewrap(value):
        return "{" + value + "}"
    

    这是html模板文件“temp.html”:

    {{var|bracewrap}}
    

    最后,这里有一个 Python 脚本,它将把所有的东西联系在一起

    import django
    from django.conf import settings
    from django.template import Template, Context
    import os
    
    #load your tags
    from django.template.loader import get_template
    django.template.base.add_to_builtins("read")
    
    # You need to configure Django a bit
    settings.configure(
        TEMPLATE_DIRS=(os.path.dirname(os.path.realpath(__file__)), ),
    )
    
    #or it could be in python
    #t = Template('My name is {{ my_name }}.')
    c = Context({'var': 'stackoverflow.com rox'})
    
    template = get_template("temp.html")
    # Prepare context ....
    print template.render(c)
    

    输出将是

    {stackoverflow.com rox}
    

    【讨论】:

      猜你喜欢
      • 2016-02-02
      • 2016-11-11
      • 1970-01-01
      • 2018-02-08
      • 1970-01-01
      • 2022-07-22
      • 2014-04-11
      • 2015-05-21
      • 2019-05-28
      相关资源
      最近更新 更多