模板与Jinja2

Django1.8+之后支持多种模板引擎, 目前可用的内置模板语言是

Django template language (DTL)Jinja2

DTLJinja2的区别

Subject DTL Jinja2
方法调用 |  
过滤器 |  
Loop Empty Argument { empty } { else }
Loop Variable    
Cycle { cycle ‘odd’ ‘even’ }  

优缺点

可以通过设置 settings.TEMPLATES 去指定使用 DTL 或者 Jinja2的templates

  • DTL的优点

    ➤ It’s batteries-included with all the functionality clearly documented within the Django docs. The official Django documentation on DTL is very extensive and easy to follow. The template code examples in the Django docs use DTL. ➤ The DTL+Django combination is much more tried and mature than the Jinja2+Django combination. ➤ Most third-party Django packages use DTL. Converting them to Jinja2 is extra work. ➤ Converting a large codebase from DTL to Jinja2 is a lot of work.

  • Jinja2的优点

    ➤ Can be used independently of Django. ➤ As Jinja2’s syntax is closer to Python’s syntax, many find it more intuitive. ➤ Jinja2 is generally more explicit, e.g. function calls in the template use parentheses. ➤ Jinja2 has less arbitrary restrictions on logic, e.g. you can pass unlimited arguments to a filter with Jinja2 vs. only 1 argument with DTL. ➤ According to the benchmarks online and our own experiments, Jinja2 is generally faster.

使用模板语言时注意点

  • CSRF and Jinja2

    Jinja2 accesses Django’s CSRF mechanism differently than DTL. To incorporate CSRF into Jinja2 templates, when rendering forms make certain to include the necessary HTML

<div style="display:none">
    <input type="hidden" name="csrfmiddlewaretoken" value="">
</div>


  • Using Django-Style Template Filters 过滤器 in Jinja2 Templates

因为过滤器是函数,所以可以把函数传给Jinjia2的环境


# core/jinja2.py

from django.contrib.staticfiles.storage import staticfiles_storage
from django.template import defaultfilters
from django.urls import reverse

from jinja2 import Environment

def environment(**options):
    env = Environment(**options)
    env.globals.update({
    'static': staticfiles_storage.url,
    'url': reverse,
    'dj': defaultfilters
    })
    return env

模板中使用

<table><tbody>
{  for purchase in purchase_list  }
    <tr>
        <a href="">
            
        </a>
    </tr>
    <tr></tr>
    <tr></tr>
{  endfor  }
</tbody></table>

或者使用view对象

# core/mixins.py

from django.template import defaultfilters

class DjFilterMixin:
    dj = defaultfilters

模板中

<table><tbody>
{  for purchase in purchase_list  }
    <tr>
        <a href="">
            
    </a>
    </tr>
    <!-- Call the django.template.defaultfilters functions from the view -->
    <tr></tr>
    <tr></tr>
{  endfor  }
</tbody></table>

  • Jinja2 的环境变量应该看作是 静态的

Jinja2 Environment

is where Jinja2 shares configuration, filters, tests, globals, and more

When the first template in your project is loaded, Jinja2 instantiates this class as what is essentially a static object
# core/jinja2.py
from jinja2 import Environment

import random

def environment(**options):
    env = Environment(**options)
    env.globals.update({
        # Runs only on the first template load! The three displays below
        # will all present the same number.
        #   
        'random_once': random.randint(1, 5)
        # Can be called repeated as a function in templates. Each call
        # returns a random number:
        #   
        'random': lambda: random.randint(1, 5),
        })
    return env
Buy me a 肥仔水!