第2节 Django模板

模板和模板引擎

  • 模板具有一定的格式或骨架,可以动态的生成HTML
  • 模板引擎决定以何种方式组织代码
  • 一个项目可以有一个或者是多个模板引擎
    • DTL
    • Jinja2

DTL

  • DTL(Django Template Language)是django)原生的模板系统
  • 直到Django1.8,唯一的模板引|擎支持

Jinja.2介绍

  • 速度更快,Python的功能齐全的开源模板引擎
  • 安装pip install jinja2

配置选项

settings.png配置模板选项TEMPLATES

  • BACKEND —— 模板引擎配置
    • django.template.backends.django.DjangoTemplates
    • django.template.backends.jinja2.Jinja2
  • DIRS —— 模板引擎按列表顺序搜索这些目录以查找模板源文件
  • APP_DIRS —— 决定模板引擎是否应该进入每个已安装的应用中查找模板
    • 每种模板引擎后端都定义了一个惯用的名称作为应用内部存放模板的子目录名称
    • DTL —— templates目录
    • Jinja2 —— jinja2目录
  • OPTIONS —— 其他选项配置

同时支持两种模板引擎

  • 添加配置模板引擎支持
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates']
    },
    {
        'BACKEND': 'django.template.backends.jinja2.Jinja2',
        'DIRS': [BASE_DIR / 'jinja2']
    },
]

同时支持两种模板引擎

  • 模板文件查找规则get_template('index..html')
    • templates/index.html
    • jinja2/index.html
  • 模板查找的顺序:
    • 按顺序查找、先根目录后模块目录

模板变量的使用

  • 语法
    • {{ variable }}
  • 当模版引擎遇到一个变量,它将计算这个变量,然后用结果替换掉它本身
  • 变量名称中不能有空格或标点符号,不能以”_”开头

渲染Pythonl中的对象

  • 语法
    • {{ object.attribute }}
  • dict类型数据的渲染
  • list/tuple类型数据的渲染
  • list/tuple嵌套dict复杂类型数据的渲染

DTL与Jinja2的使用区别

  • 注意:变量名称中不能有空格或标点符号
  • 下面的语法在DTL中不被支持
    • {object["a.b"]}
    • {object["a b"]}
  • 类中的成员方法调用不需要(),也不支持参数传递
# DTL不支持,Jinja2支持
class A():
    def display():
        return 'hello
# DTL不支持,Jinja2支持
a = A()
{{ a.display }}

模板标签的使用

  • 语法
{% tag %}
  • 循环控制
  • 条件控制
  • 模板注释
  • URL解析
  • with语句块
  • 当前时间显示
  • 继承与包含

循环控制

{% for item in data_list %}
    <li>内容</li>
    {% empty %}
    <li>暂无内容</li>
{% endfor %}
  • 循环内的变量forloop
变量 描述
forloop.first 如果是第一次迭代,为True
forloop.last 如果是最后一次迭代,为True
forloop.counter0 计数器,从0开始
forloop.counter 计数器,从1开始
  • for循环dict
{% for key,value in data.items %}
    {{key}}:{{value}}
{% endfor %}
  • 重复循环(循环中再循环)
{% cycle 'row1' 'row2' %}
  • 与Jinja2的区别
    • 循环变量forloop,Jinja2中为loop
    • List为空:{% empty %},Jinja2中为 {% else %}
    • 循环中的再循环
      • DTL:{% cycle 'odd' 'even' %}
      • Jinja2:{{ loop.cycle('odd','even')}}
    • DTL不支持continue和oreak

条件控制

{% if condition_a %}
    满足了A条件
{% elif condition_b %}
    满足了A条件
{% else %}
    都不满足
{% endif %}
  • ifequal / ifnotequal
{% ifequal a b %}
···
{% endifequal %}
  • 循环内ifchanged

模板注释

  • 添加注释{# 注释内容 #}
{% comment "简单的描述" %}
    <p>HTML内容{{ create_date }}</p>
{% endcomment %}

URL解析

  • URL标签的使用{% url 'url_name'params %}
<a href="{% url 'index' %}">首页</a>
  • statici静态文件URL解析
{% load static %}
<img src="{% static 'images/cat.jpg' %}" alt="Cat">
  • 与Jinja2的区别
    • DTL{% url 'url_name' params %}
    • Jinja2{{ url_for('index') }}

with语句块

{% with alpha=1 beta=2 %}
···
{% endwith %}

当前时间显示

{% now "jS F Y H:i" %}

模板的继承与包含

模板的抽象和继承

  • 步骤一:将可变的部分圈出来(base.html)
{% block sidebar %}
    <!-- 菜单栏的内容 -->
{% endblock %}
  • 步骤二:继承父模板只能放第一条语句
{% extends "base.html" %}
  • 步骤三:填充新的内容(index.html)
{% extends "base.html" %)
{% block sidebar %}
  <!-- 新的菜单栏的内容 -->
{% endblock %}
  • 步骤四:复用父模板的内容(可选)
{% extends "base.html" %}
{% block sidebar %}
  {{ block.super }}
  <!-- 新的菜单栏的内容 -->
{% endblock %}

在模板中添加公共部分

  • 步骤一:将可变的部分拆出来(footer.html)
<footer>
  这是页脚公共的部分
<footer>
  • 步骤二:将拆出来的部分包进来(index.html)
{% extends "base.html" %}
{% block content %}
  {{ block.super }}
  <!-- 页面主要内容区域 -->
  
  {# 公共的footer #}
  {% include "footer.html" %}
{% endblock %}

模板过滤器

什么是过滤器

  • 思考:我想对变量进行特殊处理后再渲染?
  • 举例:将英语单词转换为大写
  • 过滤器语法
    • {{ value|filter_name:params }}
    • {{ 变量|过滤器名称:参数 }}
  • 实例:使用过滤器将字母大写

内置的过滤器

  • 默认值显示
    • {{ value | default:"" }}
    • {{ value | default_if_none:"无" }}
  • 数字四舍五入显示
    • {{ value | floatformat:3 }}
  • 日期对象格式化
    • {{ value | date:"D d M Y" }}
  • 时间对象格式化
    • {{ value | time:"H:i" }}
  • 富文本内容转义显示
    • {{ value | safe }}
  • 字符串截取
    • {{ value | truncatechars:9 }}
    • {{ value | truncatechars_html:9 }}
    • {{ value | truncatewords:2 }}

自定义过滤器

使用场景

  • 思考:在什么情况下需要自定义过滤器?
  • 手机号、用户名脱敏(隐藏部分**字符串)处理

自定义过滤器

  • 步骤一:在app模块目录下新建包templatetags
  • 步骤二:实现过滤器poll_extras.py
from django import template
register = template.Library()
def warning(value):
    """将第一个字符变红"""
    return '<span class="red">' + value[O] + '</span>+value[1:]'
  • 步骤三:注册过滤器
    • 方式一:注册过滤器 register.filter('warning',warning)
    • 方式二:注册过滤器
    @register.filter(name='warning')
    def warning(value):
        pass
    
  • 步骤四:在模板中使用过滤器
{% load poll_extras %}
{{ value | warning }}

注意:

  • 添加自定义过滤器后记得重启开发服务器
  • 模块需要添加到settings.py中的INSTALLED_APPS内
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容