Flask框架学习----3.Flask之Jinja2模板

Flask框架学习,更新ing,附目录

模板简介

在这里插入图片描述在这里插入图片描述

Jinja2模板介绍和查找路径

  1. 模版介绍
      模板是一个web开发必备的模块.因为我们在渲染一个网页的时候,并不是只渲染了一个纯文本字符串,而是需要渲染一个有富文本标签的页面.这时候我们就需要使用模板了,在flask中,配套的模板是Jinja2,Jinja2的作者也是flask的作者,这个模板非常强大,并且执行效率高.官网(但不建议去官网学习,多且乱):http://jinja.pocoo.org/
  2. 查找路径
      (1) 在渲染模板的时候,默认会从项目根目录下的templates目录下查找模板,可以看一下Flask源码
      在这里插入图片描述  在这里插入图片描述
      (2)如果不想把模板文件放在templates目录下,那么可以在flask初始化的时候指定template_folder来指定模板的路径
      在这里插入图片描述
  3. Flask渲染Jinja2模板
      要渲染一个模板,通过render_template方法即可,比如:
    在这里插入图片描述在这里插入图片描述在这里插入图片描述
  4. 此时如果我们想要在index.html页面中能够动态显示xxx进入的话,该怎么做呢?显然可以通过在render_template方法中添加要传递的参数,然后将参数在页面中显示出来即可,下面就详细说明一下模拟步骤
      首先我们访问URL为:127.0.0.0:5000/的时候会进入到hello_world()方法内部,我们可以创建一个uname变量,作为用户名的表示,然后在render_template方法中作为形参传入
    在这里插入图片描述
      其次我们需要在index.html中,使用专门的模板语法来取出我们传递的username参数
    在这里插入图片描述
    在这里插入图片描述

模板传参及其技巧

  1. 在使用render_template渲染模板的时候,可以传递关键字参数(命名参数).
    模板传参
      在这里插入图片描述页面取出参数
      在这里插入图片描述
  2. 如果你的参数项过多,那么可以将所有的参数放到一个字典中,然后在传这个字典参数的时候,使用两个星号(**),将字典打散成关键字参数(也叫命名参数)
     比如:
      在这里插入图片描述  在这里插入图片描述
      在这里插入图片描述
  3. 如果不使用上面提到的**星号打散关键字的技巧也可以是,直接使用第一种方式来将context传参也可以
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

模板中使用url_for

  1. 模板中的url_for跟我们视图函数中的url_for使用起来一模一样的.也是传递视图函数的名字,也可以传递参数.使用的使用,需要在url_for左右两边加上{{url_for('func'}}
  2. 案例引入:模拟一个从首页登录的案例(仅作为模拟)
      代码流程介绍:运行程序后,输入127.0.0.1:5000/后会通过视图函数hello_world跳转到首页,并且点击登录按钮后,会通过视图函数login,再次跳转到登录页面
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      分析:可以发现在parameter.html中,采用的是将a标签中href写死的情况下进行跳转,如果以后登录的url改变了,这里就需要调整href,缺乏一定的灵活性,但是通常情况下,我们都会使用名叫login的函数作为登录的方法,换句话说URL变了,函数名不一定变,这里我们就可以使用url_for函数灵活获取URL地址
      在这里插入图片描述
      下面再介绍下,使用url_for方式进行传参的方法
  3. 传参方式
    路径式传参
      设定,在首页中点击登录按钮时,需要向login视图函数中传递name参数和age参数
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
    查询式传参
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

Jinja2过滤器_基本使用

  1. 举例子
      访问https://www.bufanbiz.com/,在说明提示时间的位置就使用到了过滤器
      在这里插入图片描述
  2. 简单使用(abs表示取绝对值)
      在这里插入图片描述
      在这里插入图片描述
  3. 简单总结
      1. 有时候我们想要在模版中对一些变量进行处理,那么就必须需要类似于Python中的函数一样,可以将这个值传到函数中,然后做一些操作。在模版中,过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功能,再返回相应的值,之后再将结果渲染到页面中。
      基本语法:{{ variable|过滤器名字 }}。使用管道符号|进行组合。

Jinja2过滤器介绍

  1. 过滤器介绍
      过滤器是通过管道符号(|)进行使用的,例如:{{ name|length }},将返回name的长度。过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功能,再返回相应的值,之后再将结果渲染到页面中。Jinja2中内置了许多过滤器,查看所有过滤器:http://jinja.pocoo.org/docs/dev/templates/#builtin-filters
  2. 常见过滤器说明
       - abs(value):返回一个数值的绝对值。 例如:-1|abs。
       - default(value,default_value,boolean=false):如果当前变量没有值,则会使用参数中的值来代替。name|default(‘xiaotuo’)——如果name不存在,则会使用xiaotuo来替代.boolean=False的情况下,只有这个变量为undefined的时候才会使用default中的值,如果在变量是一些特殊值(如None,空字符串,空列表,空字典),想要依旧使用default值的话,需要设置为boolean=True或者使用or来表示—具体详解见下一小节
       - escape(value)或e:转义字符,会将<、>等符号转义成HTML中的符号。例如:content|escape或content|e。
       - first(value):返回一个序列的第一个元素。names|first。
       - format(value,*arags,**kwargs):格式化字符串。例如以下代码:{{ “%s” - “%s”|format(‘Hello?’,“Foo!”) }}将输出:Helloo? - Foo!
       - last(value):返回一个序列的最后一个元素。示例:names|last。
       - length(value):返回一个序列或者字典的长度。示例:names|length。
       - join(value,d='+'):将一个序列用d这个参数的值拼接成字符串。
       - safe(value):如果开启了全局转义,那么safe过滤器会将变量关掉转义。示例:content_html|safe。
       - int(value):将值转换为int类型。
       - float(value):将值转换为float类型。
       - lower(value):将字符串转换为小写。
       - upper(value):将字符串转换为小写。
       - replace(value,old,new): 替换将old替换为new的字符串。
       - truncate(value,length=255,killwords=False):截取length长度的字符串。
       - striptags(value):删除字符串中所有的HTML标签,如果出现多个空格,将替换成一个空格。
       - trim:截取字符串前面和后面的空白字符。
       - string(value):将变量转换成字符串。
       - wordcount(s):计算一个长字符串中单词的个数。

Jinja2过滤器_default详解

  1. 案例场景:个性签名
      用户设置了签名,写什么就是什么
      用户没设置签名,默认给出"此人很懒,暂无任何签名"
  2. 案例1–这里的signature是没有定义的,所以会使用默认值
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
  3. 案例2—设置signature的值
      在这里插入图片描述
      在这里插入图片描述
  4. 案例3–在案例2的情况下,如果传递的signature是一些特殊值,如None,空字符串,空字典,空列表等,想要依旧让过滤器生效,也就是说依旧采用默认值,需要在defalut添加boolean=True
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
  5. 总结
      使用方式{{ value|default('默认值') }}
      如果value这个key不存在,那么就会使用default过滤器提供的默认值。
      如果value这个key存在,就不会使用default过滤器提供的默认值。但对于value的一些特殊值(例如:None、空字符串、空列表、空字典等),想使用default过滤器提供的默认值。,那么就必须要传递另外一个参数{{ value|default('默认值',boolean=True)}}
  6. 扩展
      可以使用or来替代default('默认值',boolean=True)。例如:{{ signature or '此人很懒,没有留下任何说明' }}
      以下两种写法等价
    在这里插入图片描述
      建议使用扩展中的两种写法之一,这种情况下,如果signature未定义或者是一些特殊值会自动采用默认值,如果已经定义且非特殊值,则采用signature值

Jinja2过滤器_常用过滤器

  1. 常见过滤器
      在这里插入图片描述  几个样例:
      在这里插入图片描述
      在这里插入图片描述
      truncate截取中对于任何单个字符(如中文单个汉字,英文单个字母等等)都是按1个长度来计算的
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
  2. 关于过滤器的自动转义
      Jinja2模板,默认全局 开启了自动转义功能
      1. safe过滤器:可以关闭一个字符串的自动转义。
      2. escape过滤器:对某一个字符串进行转义。
      3. autoescapejinja标签,可以对他里面的代码块关闭或开启自动转义。
      在这里插入图片描述
  3. 针对默认的全局自动转义进行验证测试
    在这里插入图片描述
     在这个页面中,如果直接通过浏览器访问,那么script部分代码会被JS引擎所识别,结果是在网页中显示一个弹窗,现在尝试一下将script部分内容保存到一个视图函数中的变量中,然后传递到html再用Jinja2语法来获取
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
     运行测试时发现,在html中显示的内容就是我们要传递的字符串,JS引擎并没有处理这部分代码,现在查看一下网页源代码
    在这里插入图片描述
     可以看到,Jinja2模板 已经将一些特殊字符进行了转义,避免了之前情况的出现,此时若我们使用safe过滤器将该字符串关闭自动转义,再次运行时就和第一次弹窗情况一样了
    在这里插入图片描述

Jinja2过滤器_自定义过滤器的步骤

  1. 只有当系统提供的过滤器不符合需求后,才须自定义过滤器,过滤器本质上就是一个函数.如果在模板中调用这个过滤器,那么就会将这个变量的值作为第一个参数传给过滤器函数,然后函数的返回值会作为这个过滤器的返回值
  2. 需要使用一个装饰器@app.template_filter('过滤器名称')
  3. 案例:创建一个删除变量中指定内容的过滤器
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

Jinja2过滤器_自定义事件处理过滤器

  1. 代码
'''
    自定义过滤器处理时间
'''
from flask import Flask,render_template
from datetime import datetime

app = Flask(__name__)

@app.template_filter('handle_time')
def handle_time(createtime):
    '''
        createtime距离现在的时间间隔
        1.如果时间间隔小于1分钟,就显示'刚刚'
        2.如果大于1分钟小于1小时,那么就显示'xx分钟前'
        3.如果大于1小时小于24小时,那么就显示'xx小时前'
        4.如果大于24h小于30天以内,那么就显示'xx天前'
        5,否则,就显示具体创建时间
    '''
    if isinstance(createtime,datetime):
        now=datetime.now()
        timestamp = (now-createtime).total_seconds()
        if timestamp<60:
            return '刚刚'
        elif timestamp>=60 and timestamp<60*60:
            minute = timestamp/60
            return "%s分钟前"%int(minute)
        elif timestamp>=60*60 and timestamp<24*60*60:
            hour = timestamp/(60*60)
            return "%s小时前"%int(hour)
        elif timestamp>=24*60*60 and timestamp<60*60*24*30:
            day = timestamp/(24*60*60)
            return "%s天前"%int(day)
        else:
            return createtime.strftime('%Y/%m/%d %H:%M')
    else:
        return createtime

@app.route('/')
def hello_world():
    create_time=datetime(2020,6,3,18,20,22)
    return render_template('time.html',create_time=create_time)

if __name__ == '__main__':
    app.run()

在这里插入图片描述
2. 效果
在这里插入图片描述

控制语句_if语句详解

  1. 控制语句:所有的控制语句都是放在{% … %}中,并且有一个语句{% endxxx %}来进行结束,Jinja中常用的控制语句有if/for...in...
  2. if语句:if语句和Python中的if类似,可以使用>,<,<=,>=,==,!=来判断,也可以通过and,or,not,()来进行逻辑合并操作
  3. 案例
      在这里插入图片描述
      在这里插入图片描述
  4. 强调:if条件判断语句必须放在{% if statement %}中间,并且还必须有结束的标签{% endif %}

控制语句_if语句应用场景

  1. 场景介绍:在网页的首页中,存在一个修改个人信息的超链接,可以实现修改个人信息的功能,当点击该按钮时会向视图函数发送请求,在请求的视图函数中会查询数据库获取到该用户的个人信息,并将个人信息返回到修改信息的页面上进行显示
  2. 代码和结果
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

控制语句_for语句01

  1. for...in...:for循环可以遍历任何一个序列包括列表,字典,元组.并且可以进行反向遍历.
  2. 案例
    在这里插入图片描述
     (1) 遍历列表
    在这里插入图片描述
    在这里插入图片描述
     (2) 遍历字典
    在这里插入图片描述
    在这里插入图片描述
     (4)遍历列表中含有字典的数据
    在这里插入图片描述
    在这里插入图片描述
     (3) 如果序列中没有值的时候,进入else,反向遍历用过滤器reverse
    在这里插入图片描述
    在这里插入图片描述
  3. for循环中包含的其他变量,可以用来获取当前遍历的状态
    loop.index:当前迭代的索引(从1开始)
    loop.index0:当前迭代的索引(从0开始)
    loop.first:是否是第一次迭代,返回True或False
    loop.last:是否是最后一次迭代,返回True或False
    loop.length:序列的长度
      在这里插入图片描述
      在这里插入图片描述
  4. 总结
      在jinja2中的for循环,跟python中的for循环基本上是一模一样的。也是for...in...的形式。并且也可以遍历所有的序列以及迭代器。但是唯一不同的是,jinja2中的for循环没有breakcontinue语句。

控制语句_for循环99乘法表案例

  1. 实现代码
      在这里插入图片描述
  2. 代码说明
      采用了双层for循环,外层for循环控制的是行数,使用range(1,10)函数,可以依次取到1-9这9个数字,形成9行,在内层for循环中,控制的是每一行中列的数量,依次取出1到取出的x+1之间的数字,并进行乘法操作即可

宏的概念及基本使用

  1. 宏的概念
      模板中的宏跟Python中的函数类似,可以传递参数,但是宏不能有返回值,可以将一些经常用到的代码片段放到宏中,然后把一些不固定的值抽取出来当成一个变量
  2. 基本使用
      (1)定义宏(这里定义了一个名为input的宏,它含有三个参数,第一个是name,后面两个存在默认值)
      在这里插入图片描述
      (2)使用宏
      在这里插入图片描述
      (3)效果
      在这里插入图片描述
  3. 注意点
      (1) 在宏定义的时候,如果存在类似函数的形参,在调用宏的时候都可以不传入,那么宏的形参就会以"有默认值的以默认值,没有默认值的默认为空"为准;此外,在调用宏的时候,参数的传递时有顺序的,以上面input为例,传递的第一个参数就会赋值给name,以此类推,如果想单独仅仅给type赋值,需要单独指定,比如{{input(type=‘text’}}
      (2) 宏的形参位置也是有要求的,没有默认值的参数必须要放在存在默认值的参数前面,如上面的input宏中name属性要在value和type前面

宏的导入和导入注意事项

  1. 导入:实际开发中,不会将宏直接定义在html页面内,这样一旦定义较多宏,那么只会造成页面比较冗杂,相对的,一般都会将宏定义放在专门的文件夹中,方便进行统一管理,哪一个页面需要使用某个宏,就需要导入宏才能使用
  2. 导入宏的两种方式
      (1) from "宏文件的路径" import 宏的名字 [as xxx],其中as表示起别名,非必选,起别名后,在后面的使用中就必须使用别名了
      {% from “macros/macros.html” import input as inp %}
      在这里插入图片描述
      在这里插入图片描述
      (2) import "宏文件的路径" as xxx [with context],其中as可以理解为将整个宏文件作为某个对象,使用其中单个宏的时候,需要用指定的xxx.宏的名称的方式
      {% import “macros/macros.html” as macros with context %}
      在这里插入图片描述
  3. 注意点
      (1) 宏文件路径,不要以相对路径去寻找,都要以templates作为绝对路径去找
      (2) 如果想要在导入宏的时候,就把当前模板的一些参数传给宏所在的模板,那么就应该在导入宏的时候使用with context
      修改视图函数,让视图函数传递一个参数到模板页面
      在这里插入图片描述
      显然传递的test参数在模板页面上就可以使用{{ test }}方式进行获取到,那么在使用下面这种导入宏的方式的前提下,想让定义宏的页面中也使用到test参数可以吗?
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述  上图方框处,原本value值是:“提交”,但是在调用宏的时候,获取不到test参数值,而显示空值
      这里就需要修改在模板页面上导入宏的方式了
      在这里插入图片描述
      在这里插入图片描述

include标签使用详解

  1. 介绍
      (1) 这个标签相当于是直接将指定的模板中的代码复制粘贴到当前位置,包括被引入模板中的样式等
      (2) include标签,如果被引用的模板想要使用include标签所在的模板中的变量,直接用就可以了,不需要使用with context,体现在下面的案例中就是:head.html可以使用首页中的变量
      (3) include的路径,也是跟import一样,直接从templates根目录下去找,不要以相对路径去找
  2. 示例
      比如一个公司的网站中顶部和底部一些信息是固定的内容,在该网站上点击不同链接中如果存在重复内容,就没必要重复写这些代码,可以直接引用
      在这里插入图片描述  在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

set和with语句以及模板中定义变量

  1. set语句
      在模板中,可以使用set语句来定义变量.示例如下:
      在这里插入图片描述  一旦定义了这个变量,那么在后面的代码中,都可以使用这个变量,类似于Python中的全局变量差不多
  2. with语句
      with语句定义的变量,只能在with语句块中使用,超过了这个代码块,就不能再使用了,类似于Python中的局部变量
      在这里插入图片描述
  3. 注意
      关于定义的变量,with语句也不一定要跟一个变量,可以定义一个空的with语句.如果需要定义只能在指定区域内有效的变量,可以set与with组合使用.
      在这里插入图片描述
      上面这个案例中,虽然使用set定义了pname变量,但是外部被with所限制了,因此pname变量只能在with语句块的范围内使用

flask项目加载静态文件

模板继承详解_理论

模板继承详解_实战

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值