【问题标题】:Is there a simple way to use django's template engine for django's own views and jinja2 engine for my own views?有没有一种简单的方法可以将 django 的模板引擎用于 django 自己的视图和 jinja2 引擎用于我自己的视图?
【发布时间】:2014-05-29 13:55:09
【问题描述】:
  • 为方便起见,我为我的 Django 项目的所有视图使用自定义 Jinja2 模板加载器,this method。因此无论我在哪里编写自己的视图函数,我都不必为 Jinja2 引擎编写或声明任何特殊的东西(因为我一开始在 settings.py 中将默认模板加载器更改为 Jinja2)。
  • 但是当我想访问使用 Django 自己视图的 url 时,例如 admin.site.urlshttp://127.0.0.1:8000/admin/,它会失败(显然)。
  • 我尝试将Django自己的admin文件夹中的所有html文件转换为Jinja2引擎可以解析的文件,但我很快放弃了,因为要转换的过滤器或标签太多,也不是很好修改源代码的想法。
  • 那么,有没有一种简单的方法可以使用 django 的模板引擎来处理 django 自己的视图和 jinja2 引擎来处理剩余的视图?谢谢。

【问题讨论】:

    标签: python django jinja2


    【解决方案1】:

    这是我的解决方案,它的理论是:对于每个templateResponse,首先尝试Django模板引擎,如果引发TemplateSyntaxError,然后尝试jinja2引擎(就像以前一样)。

    它有效,但我不确定是否有任何潜在的错误。

    import os
    import sys
    
    from django.conf import settings
    from django.core.exceptions import ImproperlyConfigured
    from django.template.base import TemplateDoesNotExist,TemplateSyntaxError
    from django.template.loader import BaseLoader
    from django.utils._os import safe_join
    from django.utils.importlib import import_module
    from django.utils import six
    import jinja2
    
    if six.PY2:
        fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
    app_template_dirs = []
    for app in settings.INSTALLED_APPS:
        try:
            mod = import_module(app)
        except ImportError as e:
            raise ImproperlyConfigured('ImportError %s: %s' % (app, e.args[0]))
        template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates')
        if os.path.isdir(template_dir):
            if six.PY2:
                template_dir = template_dir.decode(fs_encoding)
            app_template_dirs.append(template_dir)
    
    # It won't change, so convert it to a tuple to save memory.
    app_template_dirs = tuple(app_template_dirs)
    
    ALL_PATH = settings.JINJA2_TEMPLATE_DIRS + app_template_dirs
    
    class jinja2Template(jinja2.Template):
        def render(self, context):
            # flatten the Django Context into a single dictionary.
            context_dict = {}
            for d in context.dicts:
                context_dict.update(d)
            return super(jinja2Template, self).render(context_dict)
    
    class Loader(BaseLoader):
        is_usable = True
        env = jinja2.Environment(loader=jinja2.FileSystemLoader(ALL_PATH))
        env.template_class = jinja2Template
    
        def load_template(self, template_name, template_dirs=None):
            # this is the key method.
            try:
                return super(Loader,self).load_template(template_name, ALL_PATH)
            except TemplateSyntaxError:
                template = self.env.get_template(template_name)
                return template, template.filename
            except jinja2.TemplateNotFound:
                raise TemplateDoesNotExist(template_name)
    
        def get_template_sources(self, template_name, template_dirs=None):
            if not template_dirs:
                template_dirs = app_template_dirs
            for template_dir in template_dirs:
                try:
                    yield safe_join(template_dir, template_name)
                except UnicodeDecodeError:
                    raise
                except ValueError:
                    pass
    
        def load_template_source(self, template_name, template_dirs=None):
            for filepath in self.get_template_sources(template_name, template_dirs):
                try:
                    with open(filepath, 'rb') as fp:
                        return (fp.read().decode(settings.FILE_CHARSET), filepath)
                except IOError:
                    pass
            raise TemplateDoesNotExist(template_name)
    

    【讨论】:

      猜你喜欢
      • 2014-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-23
      • 2017-03-16
      • 1970-01-01
      相关资源
      最近更新 更多