【问题标题】:How do I use Django templates without the rest of Django?如何在没有 Django 其余部分的情况下使用 Django 模板?
【发布时间】:2010-09-11 00:28:16
【问题描述】:

我想在我的 (Python) 代码中使用 Django 模板引擎,但我没有构建基于 Django 的网站。如何在没有 settings.py 文件(和其他文件)且无需设置 DJANGO_SETTINGS_MODULE 环境变量的情况下使用它?

如果我运行以下代码:

>>> import django.template
>>> from django.template import Template, Context
>>> t = Template('My name is {{ my_name }}.')

我明白了:

ImportError: Settings cannot be imported, because environment variable DJANGO_SETTINGS_MODULE is undefined.

【问题讨论】:

    标签: python django templates django-templates template-engine


    【解决方案1】:

    解决方案很简单。它实际上是well documented,但不太容易找到。 (我不得不四处寻找——当我尝试了几个不同的 Google 搜索时,它没有出现。)

    以下代码有效:

    >>> from django.template import Template, Context
    >>> from django.conf import settings
    >>> settings.configure()
    >>> t = Template('My name is {{ my_name }}.')
    >>> c = Context({'my_name': 'Daryl Spitzer'})
    >>> t.render(c)
    u'My name is Daryl Spitzer.'
    

    有关您可能想要定义的一些设置的描述(作为配置的关键字参数),请参阅 Django 文档(上面链接)。

    【讨论】:

    • 从文件中获取:settings.configure(TEMPLATE_DIRS=(".",)) t = get_template('test.html')
    • settings.configure() 的文档在这里 - docs.djangoproject.com/en/1.7/topics/settings
    • 从上面的“有据可查”的链接,直到版本 1.7 都是如此。从 1.8 开始,您似乎不再需要 settings.configure() 了。
    • 如果你想包含其他模板,或者使用模板继承,Bryce上面的解决方案是必要的。
    • 我还需要在 Template 构造函数之前调用 django.setup()。
    【解决方案2】:

    Jinja2 syntax 与 Django 几乎相同,只有很少的差异,而且您获得了一个更强大的模板引擎,它还可以将您的模板编译为字节码(FAST!)。

    我用它来做模板,包括 Django 本身,它非常好。如果缺少某些您想要的功能,您也可以轻松编写扩展。

    下面是代码生成的一些演示:

    >>> import jinja2
    >>> print jinja2.Environment().compile('{% for row in data %}{{ row.name | upper }}{% endfor %}', raw=True) 
    from __future__ import division
    from jinja2.runtime import LoopContext, Context, TemplateReference, Macro, Markup, TemplateRuntimeError, missing, concat, escape, markup_join, unicode_join
    name = None
    
    def root(context, environment=environment):
        l_data = context.resolve('data')
        t_1 = environment.filters['upper']
        if 0: yield None
        for l_row in l_data:
            if 0: yield None
            yield unicode(t_1(environment.getattr(l_row, 'name')))
    
    blocks = {}
    debug_info = '1=9'
    

    【讨论】:

    • 我在我的一个项目中使用 Jinja,因为我想要一些我相当熟悉的东西,但不希望我的用户(因为它是一个可分发的应用程序)必须安装 Django。一个优点是可以使用 easy_install 安装 Jinja。
    • Django 也可以使用 easy_install 安装。
    • Jinga 还没有正式支持 Python3。据该网站称,它仍处于试验阶段。
    【解决方案3】:

    您想使用 Django 的模板有什么特别的原因吗?在我看来,JinjaGenshi 都比较优秀。


    如果您真的想要,请查看Django documentation on settings.py。特别是“使用设置而不设置DJANGO_SETTINGS_MODULE”部分。使用这样的东西:

    from django.conf import settings
    settings.configure (FOO='bar') # Your settings go here
    

    【讨论】:

      【解决方案4】:

      我也会推荐 jinja2。在djangojinja2 上有一个nice article,它提供了一些详细信息,说明为什么你应该更喜欢后者。

      【讨论】:

      • 我更喜欢 Jinja2,因为 {% set %} 语法和 Twig 模板引擎 (PHP) 相等。最好总是编写跨平台代码,但性能差异并不重要 - 例如,python 总是比 PHP 运行得慢,所以如果你需要性能,你最好用 PHP、Twig 和 Symfony2 或别的。悲伤但真实。
      • @Croll,如果您的网站执行复杂的计算,那么 python 库的速度将无与伦比,否则瓶颈是数据库,或者您可能做错了什么
      【解决方案5】:

      根据 Jinja 文档,Python 3 support is still experimental。因此,如果您使用的是 Python 3 并且性能不是问题,您可以使用 django 的内置模板引擎。

      Django 1.8 引入了对 multiple template engines 的支持,这需要更改模板的初始化方式。您必须显式配置 django 提供的默认模板引擎使用的settings.DEBUG。这是在不使用 django 其余部分的情况下使用模板的代码。

      from django.template import Template, Context
      from django.template.engine import Engine
      
      from django.conf import settings
      settings.configure(DEBUG=False)
      
      template_string = "Hello {{ name }}"
      template = Template(template_string, engine=Engine())
      context = Context({"name": "world"})
      output = template.render(context) #"hello world"
      

      【讨论】:

        【解决方案6】:

        除了其他人写的,如果你想在 Django > 1.7 上使用 Django 模板,你必须给你的 settings.configure(...) 调用 TEMPLATES 变量并像这样调用 django.setup() :

        from django.conf import settings
        
        settings.configure(TEMPLATES=[
            {
                'BACKEND': 'django.template.backends.django.DjangoTemplates',
                'DIRS': ['.'], # if you want the templates from a file
                'APP_DIRS': False, # we have no apps
            },
        ])
        
        import django
        django.setup()
        

        然后您可以像往常一样从字符串加载模板:

        from django import template   
        t = template.Template('My name is {{ name }}.')   
        c = template.Context({'name': 'Rob'})   
        t.render(c)
        

        如果您在 .configure 中写入 DIRS 变量,则从磁盘:

        from django.template.loader import get_template
        t = get_template('a.html')
        t.render({'name': 5})
        

        Django Error: No DjangoTemplates backend is configured

        http://django.readthedocs.io/en/latest/releases/1.7.html#standalone-scripts

        【讨论】:

          【解决方案7】:

          感谢各位的帮助。这里还有一个补充。需要使用自定义模板标签的情况。

          假设你在模块 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}
          

          【讨论】:

          • django.template.base.add_to_builtins("read") 为我提出了ValueError
          • 给出TemplateDoesNotExist 错误我正在使用 django 1.10.1
          【解决方案8】:

          我也会说Jinja。它绝对比 Django 模板引擎更强大,而且它独立

          如果这是现有 Django 应用程序的外部插件,您可以创建 a custom command 并在您的项目环境中使用模板引擎。像这样;

          manage.py generatereports --format=html
          

          但我认为只使用 Django 模板引擎而不是 Jinja 是不值得的。

          【讨论】:

            【解决方案9】:

            【讨论】:

              【解决方案10】:

              不要。请改用StringTemplate——一旦您了解它,就没有理由考虑任何其他模板引擎。

              【讨论】:

              • Python 端口看起来太像 Java。它不是pythonic。
              【解决方案11】:

              我同意上述声明。 Jinja 2 是一个非常好的通用 Django 模板超集。我认为他们正在努力使 Django 模板与 settings.py 的耦合度降低一些,但 Jinja 应该适合你。

              【讨论】:

                【解决方案12】:

                在运行manage.py shell 时:

                >>> from django import template   
                >>> t = template.Template('My name is {{ me }}.')   
                >>> c = template.Context({'me': 'ShuJi'})   
                >>> t.render(c)
                

                【讨论】:

                  【解决方案13】:

                  Google AppEngine 使用 Django 模板引擎,你看过他们是怎么做的吗?你可以直接使用它。

                  【讨论】:

                    猜你喜欢
                    • 2012-02-18
                    • 2016-03-06
                    • 1970-01-01
                    • 2016-03-22
                    • 2018-12-11
                    • 2011-05-06
                    • 2012-04-17
                    • 2011-08-13
                    • 1970-01-01
                    相关资源
                    最近更新 更多