• 模板层


    06 模板层

    一. 模版语法

    {{}}: 变量相关 {%%}: 逻辑相关

    1. 注释是代码的规范

    {# ... #}
    

    2. 基本数据类型传值

    int1 = 123
    float1 = 11.11
    str1 = '我也想奔现'
    bool1 = True
    list1 = ['小红', '姗姗', '花花', '茹茹']
    tuple1 = (111, 222, 333, 444)
    dict1 = {'username': 'jason', 'age': 18, 'info': '这个人有点意思'}
    set1 = {'晶晶', '洋洋', '嘤嘤'}
    
    # 基本数据类型都支持
    {{ int1 }}
    {{ float1 }}
    {{ str1 }}
    {{ bool1 }}
    {{ list1 }}
    {{ tuple1 }}
    {{ dict1 }}
    {{ set1 }}
    

    3. 函数和类传值

    def func():
        print('我被执行了')
        return '你的另一半在等你'
    
    class MyClass(object):
        def get_self(self):
            return 'self'
    
        @staticmethod
        def get_func():
            return 'func'
    
        @classmethod
        def get_class(cls):
            return 'cls'
        
        # 对象被展示到html页面上 就类似于执行了打印操作也会触发__str__方法
        def __str__(self):
            return  'cls'
    
    obj = MyClass()
    
    
    # 传递函数名会自动加括号调用 但是模版语法不支持给函数传额外的参数
    {{ func }}
    
    # 传类名的时候也会自动加括号调用(实例化)
    {{ MyClass }}
    
    # 内部能够自动判断出当前的变量名是否可以加括号调用 如果可以就会自动执行  针对的是函数名和类名
    {{ obj }}
    {{ obj.get_self }}
    {{ obj.get_func }}
    {{ obj.get_class }}
    
    
    # 总结
    '''
    1. 如果计算结果的值是可调用的,它将被无参数的调用。 调用的结果将成为模版的值。
    2. 如果使用的变量不存在, 它被默认设置为'' (空字符串) 。
    '''
    

    4. 模版语法的取值

    django模版语法的取值 是固定的格式 只能采用“句点符”.

    {{ dict1.username }}
    {{ list1.0 }}</p>
    {{ dict1.hobby3.info }}
    

    5. 模板语法的优先级

    .在模板语言中有特殊的含义。当模版系统遇到点.,它将以这样的顺序查询:

    '''
    1. 字典查询(Dictionary lookup)
    2. 属性或方法查询(Attribute or method lookup)
    3. 数字索引查询(Numeric index lookup)
    '''
    

    二. Filters过滤器(注意: 过滤器只能最多有两个参数)

    过滤器就类似于是模版语法内置的 内置方法.

    django内置有60多个过滤器我们这里了解一部分即可

    过滤器语法: {{数据|过滤器:可选参数}}

    注意事项:

    1. 过滤器支持“链式”操作。即一个过滤器的输出作为另一个过滤器的输入。
    2. 过滤器可以接受参数,例如:{{ sss|truncatewords:30 }},这将显示sss的前30个词。
    3. 过滤器参数包含空格的话,必须用引号包裹起来。比如使用逗号和空格去连接一个列表中的元素,如:{{ list|join:', ' }}
    4. '|'左右没有空格没有空格没有空格
    

    Django的模板语言中提供了大约六十个内置过滤器我们这里介绍14种:

    # 统计长度: 作用于字符串和列表。
        {{ str1|length }}
        
        
    # 默认值: 第一个参数布尔值是True就展示第一个参数的值否则就展示冒号后面的值
        {{ bool1|default:'谁的布尔值为True谁就展示' }}
        
        
    # 文件大小:
        {{ file_size|filesizeformat }}  # 9.8 KB 
        
        
    # 日期格式化:  将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等
        {{ current_time|date }}         # May 29, 2020
        {{ current_time|date:'Y-m-d' }}      # 2020-05-29
        {{ current_time|date:'Y-m-d H:i:s' }}    # 2020-05-29 01:31:09
        
        
    # 切片操作: 支持步长
        {{ list1|slice:'0:4:2' }}
        
        
    # 切取字符: 如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾 (注意: 包含这三个点)
        {{ info|truncatechars:9 }}   
        
        
    # 切取单词: 不包含三个点 按照空格切取, 不是识别单词语法
        {{ msg|truncatewords:3 }}    
        
        
    # 移除特定的字符:
        {{ msg|cut:' '}}    
        
    
    # 拼接操作: 
        # join
            {{ info|join:'$' }}
        # 加法: 数字就相加  字符就拼接
            {{ int1|add:float1 }}
            {{ str1|add:str1 }} 
        
        
    # 转义!!!!:
        # 后端的转义
        from django.utils.safestring import mark_safe
        html_safe = mark_safe('<h1>哈哈哈</h1>')
    
        {{ html }}           # 普通的标签使用模板, 任然是模板
        {{ html_safe }}      # 后端的转义传值
        {{ html|safe }}      # 前端的转义    
    

    date参数介绍:

    格式化字符 描述 示例输出
    a 'a.m.''p.m.'(请注意,这与PHP的输出略有不同,因为这包括符合Associated Press风格的期间) 'a.m.'
    A 'AM''PM' 'AM'
    b 月,文字,3个字母,小写。 'jan'
    B 未实现。
    c ISO 8601格式。 (注意:与其他格式化程序不同,例如“Z”,“O”或“r”,如果值为naive datetime,则“c”格式化程序不会添加时区偏移量(请参阅datetime.tzinfo) 。 2008-01-02T10:30:00.000123+02:002008-01-02T10:30:00.000123如果datetime是天真的
    d 月的日子,带前导零的2位数字。 '01''31'
    D 一周中的文字,3个字母。 “星期五”
    e 时区名称 可能是任何格式,或者可能返回一个空字符串,具体取决于datetime。 '''GMT''-500''US/Eastern'
    E 月份,特定地区的替代表示通常用于长日期表示。 'listopada'(对于波兰语区域,而不是'Listopad'
    f 时间,在12小时的小时和分钟内,如果它们为零,则分钟停留。 专有扩展。 '1''1:30'
    F 月,文,长。 '一月'
    g 小时,12小时格式,无前导零。 '1''12'
    G 小时,24小时格式,无前导零。 '0''23'
    h 小时,12小时格式。 '01''12'
    H 小时,24小时格式。 '00''23'
    i 分钟。 '00''59'
    I 夏令时间,无论是否生效。 '1''0'
    j 没有前导零的月份的日子。 '1''31'
    l 星期几,文字长。 '星期五'
    L 布尔值是否是一个闰年。 TrueFalse
    m 月,2位数字带前导零。 '01''12'
    M 月,文字,3个字母。 “扬”
    n 月无前导零。 '1''12'
    N 美联社风格的月份缩写。 专有扩展。 'Jan.''Feb.''March''May'
    o ISO-8601周编号,对应于使用闰年的ISO-8601周数(W)。 对于更常见的年份格式,请参见Y。 '1999年'
    O 与格林威治时间的差异在几小时内。 '+0200'
    P 时间为12小时,分钟和'a.m。'/'p.m。',如果为零,分钟停留,特殊情况下的字符串“午夜”和“中午”。 专有扩展。 '1 am''1:30 pm' / t3>,'midnight','noon','12:30 pm' / T10>
    r RFC 5322格式化日期。 'Thu, 21 Dec 2000 16:01:07 +0200'
    s 秒,带前导零的2位数字。 '00''59'
    S 一个月的英文序数后缀,2个字符。 'st''nd''rd''th'
    t 给定月份的天数。 28 to 31
    T 本机的时区。 'EST''MDT'
    u 微秒。 000000 to 999999
    U 自Unix Epoch以来的二分之一(1970年1月1日00:00:00 UTC)。
    w 星期几,数字无前导零。 '0'(星期日)至'6'(星期六)
    W ISO-8601周数,周数从星期一开始。 153
    y 年份,2位数字。 '99'
    Y 年,4位数。 '1999年'
    z 一年中的日子 0365
    Z 时区偏移量,单位为秒。 UTC以西时区的偏移量总是为负数,对于UTC以东时,它们总是为正。 -4320043200

    三. 标签

    1. for循环

    forloop.first 第一次循环返回True, 其余返回False
    forloop.last 最后一次循环返回False, 其余返回True
    forloop.counter 当前循环次数. 从1开始
    forloop.counter0 当前循环索引. 从0开始
    forloop.revcounter 当前循环次数取反
    forloop.revcounter0 当前循环索引取反
    forloop.parentloop 本层循环的外层循环

    展示格式:

    {'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 4, 'revcounter0': 3, 'first': True, 'last': False}
    {'parentloop': {}, 'counter0': 1, 'counter': 2, 'revcounter': 3, 'revcounter0': 2, 'first': False, 'last': False}
    {'parentloop': {}, 'counter0': 2, 'counter': 3, 'revcounter': 2, 'revcounter0': 1, 'first': False, 'last': False}
    {'parentloop': {}, 'counter0': 3, 'counter': 4, 'revcounter': 1, 'revcounter0': 0, 'first': False, 'last': True}
    {% for foo in list1 %}
        <p>{{ forloop }}</p>
        <p>{{ foo }}</p>  # 一个个元素
    {% endfor %}
    

    2. if判断

    # if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断
    {% if bool1 %}
        <p>1111</p>
    {% elif int1 %}
        <p>2222</p>
    {% else %}
        <p>3333</p>
    {% endif %}
    

    3. for与if混合使用

    Copy{% for foo in list1 %}
        {% if forloop.first %}
            <p>这是我的第一次</p>
        {% elif forloop.last %}
            <p>这是最后一次啊</p>
        {% else %}
            <p>上面都不是才轮到我</p>
        {% endif %}
    
        {% empty %}
            <p>for循环的可迭代对象内部没有元素 根本没法循环</p>
    {% endfor %}
    

    4. 处理字典values,keys,items方法

    {% for foo in dict1.values %}
        <p>{{foo}}</p>
    {% endfor %}
    
    {% for foo in dict1.keys %}
        <p>{{foo}}</p>
    {% endfor %}
    
    {% for foo in dict1.items %}
        <p>{{foo}}</p>
    {% endfor %}
    

    5. with起别名

    在with语法内就可以通过as后面的别名快速的使用到前面非常复杂获取数据的方式

    dict1 = {'username': 'egon', 'hobby': ['吃', '喝', '玩', {'info': '他喜欢吃生蚝!!!'}]}
    
    # 书写方式一: as语句
    {% with dict1.hobby.3.info as nb %}
        <p>{{ nb }}</p>
        {# 与上面等同, 但是长语句, 还是使用with赋值来进行 #}
        <p>{{ dict1.hobby.3.info }}</p>
    {% endwith %}
    
    
    # 书写方式二: 赋值
    {% with nb=dict1.hobby.3.info %}
        <p>{{ nb }}</p>
        {# 与上面等同, 但是长语句, 还是使用with赋值来进行 #}
        <p>{{ dict1.hobby.3.info }}</p>
    {% endwith %}
    

    四. 自定义过滤器、标签、inclusion_tag

    1. 准备步骤

    1. 在应用下创建一个名字”必须“叫templatetags文件夹
    2. 在该文件夹内创建“任意”名称的py文件
    3. 在该py文件内"必须"先书写下面两句话(单词一个都不能错)
        from django import template
        register = template.Library()
    

    2. 自定义过滤器

    强调: 自定义过滤器函数, 最大只能设有2个形参

    from .templatetags.mytag import register
    @register.filter(name='my_sum')
    def abc(v1, v2):  # abc函数名任意. 导入自定义过滤器使用的是上面指定的name的值
        return v1 + v2
    
    
    # 使用: (注意: 先导入我们自定义filter那个文件mytag)
    {% load mytag %}
    <p>{{ int1|my_sum:100 }}</p>
    

    3. 自定义标签

    # 自定义标签: 数可以有多个 类似于自定义函数
    from .templatetags.mytag import register
    @register.simple_tag(name='my_join')
    def abc(a, b, c, d):  # abc函数名任意. 导入自定义标签使用的是上面指定的name的值
        return f'{a}-{b}-{c}-{d}'
    
    # 使用: 标签多个参数彼此之间空格隔开(注意: 先导入我们自定义filter那个文件mytag)
    {% load mytag %}
    p>{% my_join 'json' 123 123 123 %}</p>
    

    4. 自定义inclusion_tag

    img

    '''
    内部原理:
        先定义一个方法 
        在页面上调用该方法 并且可以传值
        该方法会生成一些数据然后传递给一个html页面
        之后将渲染好的结果放到调用的位置
    '''
    from .templatetags.mytag import register
    @register.inclusion_tag('left_memu.html')  # 注意: 这里传的是渲染的HTML文件, 不需要指定关键字name
    def left(n):
        data = ['第{}项'.format(i) for i in range(n)]
        # 第一种: 将data传递给left_menu.html
        # return {'data':data}
    
        # 第二种: 将data传递给left_menu.html
        return locals()
    
    
    # left_memu.html
    {% for foo in data %}
        {% if forloop.first %}
            <p>{{foo}}</p>
        {% elif forloop.last %}
            <p>{{ foo }}</p>
        {% endif %}
    {% endfor %}
    
    
    # index使用(注意: 先导入我们自定义filter那个文件mytag)
    {% load mytag %}
    {% left 5 %}
    

    五. 模板的继承

    # 模版的继承 你自己先选好一个你要想继承的模版页面
    {% extends 'home.html' %}
    
    
    # 继承了之后子页面跟模版页面长的是一模一样的 你需要在模版页面上提前划定可以被修改的区域
    {% block content %}
    	模版内容
    {% endblock %}
    
    
    # 子页面就可以声明想要修改哪块划定了的区域
    {% block content %}
    	子页面内容
    {% endblock %}
    
    
    # 一般情况下模版页面上应该至少有三块可以被修改的区域, 这样每一个子页面就都可以有自己独有的css代码 html代码 js代码
    {% block css %}
        1.css区域
    {% endblock %}
    
    {% block content %}
        2.html区域
    {% endblock %}
    
    {% block js %}
        3.js区域
    {% endblock %}
    
    
    """
    一般情况下 模版的页面上划定的区域越多 那么该模版的扩展性就越高
    但是如果太多 那还不如自己直接写
    """
    

    六. 模版的导入

    """
    将页面的某一个局部当成模块的形式
    哪个地方需要就可以直接导入使用即可
    """
    '''静态导入'''
    {% include 'wasai.html' %}
    
    
    '''动态导入'''
    # 被导入的text.html
    <p>{{ name }}</p>   {# 这里的name就是"egon"#}
    
    # 导入html的文件
    {% include 'text.html' with name='"egon"' %}
        
        
    # 不过上面的导入的参数是写死的. 如果你想动态的通过模板语法传参, 你可以这样
    {% include 'text.html' with name=username %}    {#注意哦! 这里的username是视图层传过来的哦!#}
    # 被导入文件中如果想{{ name }}模板以后是字符串的格式你可以这也指定即可!
    <p>'{{ name }}'</p>   {#注意: 如果不加引号, 这种字符串的格式的话, 那么name模板传值以后就是一个变量.#}
    

    七. 总结

    # 模板语法的母亲 -> 注释
        {# #}
    
    # 模板语法2种书写语法
        # 变量相关: {{}}
        # 逻辑相关: {%%}
    
    # 支持的数据类型:
        # 基本数据类型: int float bool str tuple list set dict
        # 函数和类: function, class
            注意:
            1. 默认调用拿到的是返回值.
            2. 无法传值. 如果需要传值的类型, 那么这个模板语法就不会生效.
            3. 类中定义__str__方法, {{obj}}会触发其执行.
    
    # 模板语法的取值:
        固定格式. 句点符. 支持连点, 支持索引, 支持键.
        例子: {{ user.name.0.1.0.info }}
    
    
    # 过滤器: 最多只能有2个参数
        # 语法: {{ 数据|过滤器:可选参数 }}
        # 过滤器介绍:
            |length               获取长度
            |default:默认值        指定默认值. 前面布尔值为False才展示后面指定的参数 内部使用return v1 or v2
            |filesizeformat       返回人性化文件大小格式KB MB....
            |date:'Y-m-d'         返回 年-月-日 时间格式
            |slice:'0:4:2'        切片 支持步长
            |truncatechars:9      截取字符 包含三点
            |truncatewords:9      截取单词 不包含三点 以空格区分
            |cut:' '              移除特定字符
            |join:'$'             拼接操作
            |add:99               数字就加  字符就拼接
            |safe                 前端 取消转义
            from django.util.safestring import mark_safe
            res = mark_safe('<h1>我是你爸爸</h1>')
            {{ res }}             后端 取消转义
    
    # 标签
        # for循环
            {% for i in user_list %}
                {{ forloop }}
                forloop.first         循环到第一次  True
                forloop.last          循环到最后一次 False
                forloop.counter       当前循环次数
                forloop.counter0      当前循环索引
                forloop.revcounter    当前循环次数取反
                forloop.revcounter0   当前循环索引取反
            {% endfor %}
    
        # if判断
            {% if 条件 %}
                ...
            {% elif %}
                ...
            {% else %}
                ...
            {% endif %}
    
        # for与if混合使用
            {% for i in user_list %}
                {% if forloop.first %}
                    ...
                {% if forloop.last %}
                    ...
                {% endfor %}
                {% empty %}
                    迭代对象为空时触发
            {% endfor %}
    
        # 处理字典的values, keys, items方法
        # with取别名
            {% with user.name.0.1.0.info as xxx %}
            {% with xxx=user.name.0.1.0.info %}
                {{ xxx }}
            {% endwith  %}
    
    
    # 自定义过滤器
        # 三步骤:
            1. 先在需要使用过滤器的应用中创建templatetags文件夹
            2. 接着进入文件夹中创建任意名称的.py文件. -->  mytag.py
            3. 写入以下固定格式的内容:
                from django import template
                register = template.Library()
    
        # 自定义过滤器: 最多2个参数
            # 视图层定义
                from templatetags.mytag import register
                 @register.filter(name='过滤器名称 -> my_sum')
                 def 任意函数名(v1, v2):
                    return v1 + v2
            # 模板层使用
                {% load mytag %}
                {{ v1|my_sum:v2 }}
    
        # 自定义标签: 任意参数
            # 视图层定义
                from templatetags.mytag import register
                @register.simple_tag(name='标签名称 -> my_join')
                def 任意函数名(a, b, c, d):
                    return f'{a}-{b}-{c}-{d}'
    
            # 模板层使用
                {% load mytag %}
                {{ my_join 111 222 333 444 }}
    
        # 自定义inclusion_tag
            # 视图层定义
               from templatetags.mytag import register
                @register.inclusion_tag('需要传递数据的html文件 -> index.py')
                def left(n):
                    data = [f'第{i}项' for i in range(n)]
                    return locals()          # 传递数据方式1
                    # return {"data": data}  # 传递数据方式2
    
            # index.py定义
                <ul>
                {% for item in data %}
                    <li>{{ item }}</li>
                {% endfor %}
                </ul>
    
            # 模板层使用
                {% load mytag %}
                {% left 5 %}
    
    # 模板的继承
        # 子页面声明需要继承的模板页面
            {% extends '模板页面名' %}
    
        # 需要被划分模板页面中的某块区域
            {% block context %}
                ...
            {% endblock %}
    
        # 子页面声明替换区域
            {% block context %}
                ...
            {% endblock %}
    
        # 一般一情况下子页面有3种独立的形式. 提示: 太多不如不继承
            js, css, html
    
    # 模板的导入
        {% include '.html' %}
    
  • 相关阅读:
    修改项目名称
    Servlet中request、response、ServletContext 及其常用方法
    Servlet生命周期、常用提交方式、中文乱码问题、重定向和请求转发
    JavaScript基础(三) 事件
    JavaScript基础(二) DOM
    JavaScript基础(一)
    css基础:样式之定位、样式之隐藏、二级菜单、多个列表转表格、图片精灵技术
    css基础:表格样式、一级菜单、BFC浮动影响
    css基础及其实例:常用选择器、颜色五中写法、字体样式、自定义字体、盒模型及其样式设置
    HTML元素标签及表单元素详解
  • 原文地址:https://www.cnblogs.com/wait59/p/13839842.html
Copyright © 2020-2023  润新知