django-原理-模板使用&内置模板
配置模板引擎
settings.py中设置TEMPLATES内容,是配置中的list
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            # ... some options here ...
        },
    },
]
BACKEND是模板引擎api,默认的是
django.template.backends.django.DjangoTemplates
#和
django.template.backends.jinja2.Jinja2
配置包含两项
DIRS		查找模板的目录
APP_DIRS	是否需要到安装的app查找模板
用法
加载模板
django.template.loader定义了load模板的方法
#load指定名字的模板,返回template对象
get_template(template_name, using=None)
找不到会抛TemplateDoesNotExist``TemplateSyntaxError
#load指定名字的模板list,返回第一个匹配的模板
select_template(template_name_list, using=None)
如果load失败了,会抛异常TemplateDoesNotExist``TemplateSyntaxError
render
Template.render(context=None, request=None)
#context如果提供,是一个字典
#request是一个HttpRequest
模板的查找例子:在下面的配置中
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            '/home/html/example.com',
            '/home/html/default',
        ],
    },
    {
        'BACKEND': 'django.template.backends.jinja2.Jinja2',
        'DIRS': [
            '/home/html/jinja2',
        ],
    },
]
如果调用get_template('story_detail.html')会按照如下的顺序查找
/home/html/example.com/story_detail.html ('django' engine)
/home/html/default/story_detail.html ('django' engine)
/home/html/jinja2/story_detail.html ('jinja2' engine)
入果调用select_template(['story_253_detail.html', 'story_detail.html'])会按照如下查找
/home/html/example.com/story_253_detail.html ('django' engine)
/home/html/default/story_253_detail.html ('django' engine)
/home/html/jinja2/story_253_detail.html ('jinja2' engine)
/home/html/example.com/story_detail.html ('django' engine)
/home/html/default/story_detail.html ('django' engine)
/home/html/jinja2/story_detail.html ('jinja2' engine)
可以获取子目录下的模板
get_template('news/story_detail.html')
使用同样的TEMPLATES配置,加载顺序
/home/html/example.com/news/story_detail.html ('django' engine)
/home/html/default/news/story_detail.html ('django' engine)
/home/html/jinja2/news/story_detail.html ('jinja2' engine)
为了提高加载和渲染模板的方便性,提供了一些捷径;
render_to_string
render_to_string(template_name, context=None, request=None, using=None)
#会像get_template()一样加载模板,并且马上render渲染
template_name
context
request
using			额外的模板引擎名
render_to_string例子
from django.template.loader import render_to_string
rendered = render_to_string('my_template.html', {'foo': 'bar'})
可以直接使用配置引擎
from django.template import engines
django_engine = engines['django']
template = django_engine.from_string("Hello {{ name }}!")
这个engines字典
内置的backends
DjangoTemplates类
设置到django.template.backends.django.DjangoTemplates使用django引擎
当APP_DIRS设置为ture,DjangoTemplates引擎会从安装的app子目录中查找模板
DjangoTemplates选项
autoescape			boolean值,控制HTML autoescaping使能,默认True;如果设置为False,返回non-HTML模板
context_processors	
debug
loaders
string_if_invalid
file_charset
libraries
builtins
Jinja2类
需要先安装jinja2
把BACKEND设置为django.template.backends.jinja2.Jinja2配置jinja2引擎
当APP_DIRS设置为true,Jinja2引擎从安装app的子目录中查找
在OPTIONS中最重要的入口是environment,它默认是jinja2.Environment
选项
'autoescape': True
'loader': a loader configured for DIRS and APP_DIRS
'auto_reload': settings.DEBUG
'undefined': DebugUndefined if settings.DEBUG else Undefined
渲染是,jinjia2会自动添加request、csrf_input、csrf_token到context中
如果需要使用jinja特定的api,必须把它们配置到环境变量中
myproject/jinja2.py
from __future__ import absolute_import  # Python 2 only
from django.contrib.staticfiles.storage import staticfiles_storage
from django.urls import reverse
from jinja2 import Environment
def environment(**options):
    env = Environment(**options)
    env.globals.update({
        'static': staticfiles_storage.url,
        'url': reverse,
    })
    return env
把environment选项设置为myproject.jinja2.environment
然后就可以使用如下的结构
<img src="{{ static('path/to/company-logo.png') }}" alt="Company Logo">
<a href="{{ url('admin:index') }}">Administration</a>
tags和filter的概念在Django和jinja2中都有;
jinja2不需要context处理器
定制模板后端
模板后端需要继承类django.template.backends.base.BaseEngine
实现get_template()和可选的from_string()
foobar 模板例子
from django.template import TemplateDoesNotExist, TemplateSyntaxError
from django.template.backends.base import BaseEngine
from django.template.backends.utils import csrf_input_lazy, csrf_token_lazy
import foobar
class FooBar(BaseEngine):
    # Name of the subdirectory containing the templates for this engine
    # inside an installed application.
    app_dirname = 'foobar'
    def __init__(self, params):
        params = params.copy()
        options = params.pop('OPTIONS').copy()
        super(FooBar, self).__init__(params)
        self.engine = foobar.Engine(**options)
    def from_string(self, template_code):
        try:
          return Template(self.engine.from_string(template_code))
        except foobar.TemplateCompilationFailed as exc:
            raise TemplateSyntaxError(exc.args)
    def get_template(self, template_name):
        try:
            return Template(self.engine.get_template(template_name))
        except foobar.TemplateNotFound as exc:
            raise TemplateDoesNotExist(exc.args, backend=self)
        except foobar.TemplateCompilationFailed as exc:
            raise TemplateSyntaxError(exc.args)
class Template(object):
    def __init__(self, template):
        self.template = template
    def render(self, context=None, request=None):
        if context is None:
            context = {}
        if request is not None:
            context['request'] = request
            context['csrf_input'] = csrf_input_lazy(request)
            context['csrf_token'] = csrf_token_lazy(request)
        return self.template.render(context)
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号