6. 模板继承
模板继承和类的继承含义是一样的,主要是为了提高代码重用,减轻开发人员的工作量。
父模板:
如果发现在多个模板中某些内容相同,那就应该把这段内容定义到父模板中。
标签block:
用于在父模板中预留区域,留给子模板填充差异性的内容,预留区域的名字不能相同。 为了更好的可读性,建议给endblock标签也写上名字,这个名字与对应的block名字相同。父模板中也可以使用传递过来的数据。
语法:
{% block 名称 %} 预留区域,可以编写默认内容,也可以不编写默认内容 {% endblock 名称 %}
子模板:
标签extends:继承,写在子模板文件的第一行。
语法:
{% extends "父模板路径" %}
填充父模板中指定名称的预留区域。
子模版不用填充父模版中的所有预留区域,如果子模版没有填充,则使用父模版定义的默认值。
{% block 名称 %} 重写预留区域 {% endblock 名称 %}
父模板:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title> {% block title %} 页面标题 {% endblock title %} </title> </head> <body> {% block header %} <h1>页面的顶部</h1> {% endblock header %} {% block main %} <h1>页面的主要部分</h1> {% endblock main %} {% block footer %} <h1>页面的底部</h1> {% endblock footer %} </body> </html>
继承父模板重写index.html:
{# 继承父模板 #} {% extends "base.html" %} {# 重写页面标题区域 #} {% block title %} 张三的个人介绍 {% endblock title %} {# 重写页面的主体区域 #} {% block main %} <h1>hello world</h1> {# name 为模板等待接收的数据,需要View查询数据库传入模板 #} <h1>你好 {{ name }}</h1> <p>年龄:{{ age }}</p> <p> {% if age < 10 %} 年龄小于10 {% elif age >= 10 and age < 20 %} 年龄大于10小于20 {% else %} 年龄大于20 {% endif %} </p> <p>生日:{{ birthday|date:'Y-m-d H:i:s' }}</p> <p>朋友:</p> <ul> {# for 循环 #} {% for friend in friends %} {# forloop.counter 获取循环的次序,forloop.count0 获取下标 #} <li>{{ forloop.counter }} {{ forloop.counter0 }} {{ friend }}</li> {% endfor %} </ul> {# 获取列表中的某个元素,使用点+下标的方式进行获取 #} <p>女朋友:{{ friends.2 }}</p> {# 获取字典中的某个元素,使用点+key的形式获取 #} <p>第一年的薪资:{{ money.2019 }}</p> {% endblock %} {# 不需要底部区域,重写底部区域 #} {% block footer %}{% endblock %}
7. jinja2模板
Jinja2:是 Python 下一个被广泛应用的模板引擎,是由Python实现的模板语言,他的设计思想来源于 Django 的模板引擎,并扩展了其语法和一系列强大的功能,尤其是Flask框架内置的模板语言。
7.1 安装jinja2模板
pip install jinja2
pip3 install jinjia2 -i https://pypi.tuna.tsinghua.edu.cn/simple
7.2 Django配置jinja2
在settings.py文件:
TEMPLATES = [ { # 'BACKEND': 'django.template.backends.django.DjangoTemplates', # 修改为jinja2模板 'BACKEND': 'django.template.backends.jinja2.Jinja2', 'DIRS': [ os.path.join(BASE_DIR, 'template') ], 'APP_DIRS': True, 'OPTIONS': { # 默认的 # 'environment': 'jinja2.Environment', 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
报错的话,使用下面的配置设置:
ERRORS: ?: (admin.E403) A 'django.template.backends.django.DjangoTemplates' instance must be configured in TEMPLATES in order to use the admin application.
TEMPLATES = [ { # 'BACKEND': 'django.template.backends.django.DjangoTemplates', # 修改为jinja2模板 'BACKEND': 'django.template.backends.jinja2.Jinja2', 'DIRS': [ os.path.join(BASE_DIR, 'template') ], 'APP_DIRS': True, 'OPTIONS': { # 设置jinja2的环境变量 # 默认设置就为这个,可以不用配置该项 # 'environment': 'jinja2_env.environment', 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [ os.path.join(BASE_DIR, 'template') ], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
7.3 jinja2模板与Django自带模板的区别
- jinja2模板没有多行注释
{% comment %} 注释内容 {% endcomment %}
- jinja2模板中的过滤器使用的就是函数,不为
变量|过滤器:参数
,如:在Django自带的模板中date过滤器的写法为birthday|date:'Y-m-d H:i:s'
,在jinja2中直接写函数形式date(birthday)
- jinja2中不存在forloop,使用的为loop,jinja2中的loop:
{# 继承父模板 #} {% extends "base.html" %} {# 重写页面标题区域 #} {% block title %} 张三的个人介绍 {% endblock title %} {# 重写页面的主体区域 #} {% block main %} <h1>hello world</h1> {# name 为模板等待接收的数据,需要View查询数据库传入模板 #} <h1>你好 {{ name }}</h1> <p>年龄:{{ age }}</p> <p> {% if age < 10 %} 年龄小于10 {% elif age >= 10 and age < 20 %} 年龄大于10小于20 {% else %} 年龄大于20 {% endif %} </p> {# <p>生日:{{ birthday|date:'Y-m-d H:i:s' }}</p>#} <p>朋友:</p> <ul> {# for 循环 #} {% for friend in friends %} {# forloop.counter 获取循环的次序,forloop.count0 获取下标 #} <li>{{ loop.index }} {{ loop.index0 }} {{ friend }}</li> {% endfor %} </ul> {# 获取列表中的某个元素,使用点+下标的方式进行获取 #} <p>女朋友:{{ friends.2 }}</p> {# 获取字典中的某个元素,使用点+key的形式获取 #} <p>第一年的薪资:{{ money.first }}</p> {% endblock %} {# 不需要底部区域,重写底部区域 #} {% block footer %}{% endblock %}
7.4 jinja2过滤器
在jinja2_env.py文件中设置jinja2的过滤器.
jinja2_env.py 定义在项目的文件夹目录下
from jinja2 import Environment # 导入Django中模板的过滤器函数 from django.template.defaultfilters import date def environment(**options): # 创建Environment实例 env = Environment(**options) # 指定jinja2的函数执行django的指定过滤器 env.globals.update({ 'data': date }) return env
修改配置jinja2的环境配置:
TEMPLATES = [ # jinja2模板配置 { # 'BACKEND': 'django.template.backends.django.DjangoTemplates', # 修改为jinja2模板 'BACKEND': 'django.template.backends.jinja2.Jinja2', 'DIRS': [ os.path.join(BASE_DIR, 'template') ], 'APP_DIRS': True, 'OPTIONS': { # 设置jinja2的环境变量 # jinja2的默认环境 # 'environment': 'jinja2.Environment', # 我们自己的jinja2环境 'environment': 'django_pro2.jinja2_env.environment', 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, # Django自带模板配置 { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [ os.path.join(BASE_DIR, 'template') ], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
使用jinja2过滤器:
{# 继承父模板 #} {% extends "base.html" %} {# 重写页面标题区域 #} {% block title %} 张三的个人介绍 {% endblock title %} {# 重写页面的主体区域 #} {% block main %} <h1>hello world</h1> {# name 为模板等待接收的数据,需要View查询数据库传入模板 #} <h1>你好 {{ name }}</h1> <p>年龄:{{ age }}</p> <p> {% if age < 10 %} 年龄小于10 {% elif age >= 10 and age < 20 %} 年龄大于10小于20 {% else %} 年龄大于20 {% endif %} </p> {# 使用jinja2中的过滤器 #} {# 第一个参数为需要进行过滤处理的数据,第二个参数为过滤器需要传递的参数 #} <p>生日:{{ date(birthday, 'Y-m-d H:i:s') }}</p> <p>朋友:</p> <ul> {# for 循环 #} {% for friend in friends %} {# forloop.counter 获取循环的次序,forloop.count0 获取下标 #} <li>{{ loop.index }} {{ loop.index0 }} {{ friend }}</li> {% endfor %} </ul> {# 获取列表中的某个元素,使用点+下标的方式进行获取 #} <p>女朋友:{{ friends.2 }}</p> {# 获取字典中的某个元素,使用点+key的形式获取 #} <p>第一年的薪资:{{ money.first }}</p> {% endblock %} {# 不需要底部区域,重写底部区域 #} {% block footer %}{% endblock %}
7.5 修改pycharm的模板引擎
7.6 自定义过滤器
在jinja2_env.py文件中自定义过滤器
from jinja2 import Environment # 导入Django中模板的过滤器函数 from django.template.defaultfilters import date def environment(**options): # 创建Environment实例 env = Environment(**options) # 指定jinja2的函数执行django的指定过滤器 env.globals.update({ 'date': date, # 将自定义的过滤器添加 'do_listreverse': do_listreverse }) return env # 1.自定义过滤器 def do_listreverse(li): if li == "B": return "哈哈"
{# 继承父模板 #} {% extends "base.html" %} {# 重写页面标题区域 #} {% block title %} 张三的个人介绍 {% endblock title %} {# 重写页面的主体区域 #} {% block main %} <h1>{{ do_listreverse('B') }}</h1> {% endblock %} {# 不需要底部区域,重写底部区域 #} {% block footer %}{% endblock %}