Flask模板jinja2

Posted fengzi759

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask模板jinja2相关的知识,希望对你有一定的参考价值。

  1. 模板预热

    • 在渲染模板的时候,默认会从项目根目录下的‘templates‘目录下查找模板。

    • 如果不想把模板文件放在‘templates‘目录下,那么可以在‘Flask‘初始化的时候指定‘template_folder‘来指定模板的路径

  2. 模块传参数

    • 1.在使用‘render_template‘渲染模板的时候,可以传递关键字参数。以后直接在模板中使用就可以了

    • 2.如果你的参数过多,那么可以将所有的参数放到一个字典中,然后再传这个字典参数的时候,使用两个星号,将字典打散成关键字参数

    • 3.如果想要再html中访问我们传递的参数 比如传递的是 username=‘xiaoxin‘

      • 如果是关键字参数 直接{{username}},就可以将我们的参数对应的内容映射到前端页面上

      • 如果传递的是字典 比如

        • content = {‘name‘:‘age‘} 那么就可以{{content.name}} 就能将里面的age映射到前端上

        • 使用**content 相当于将字典里面的参数,变成关键字传参,然后就可以直接{{username}},将我们参数的内容映射到前端网页上

  3. 模板中使用url_for

    • 模板中的url_for跟我们后台视图函数中的url_for使用起来基本是一模一样的,也是传递视图函数的名字,也可以传递参数

    • 再html里面使用的时候,需要再urlfor 左右两边加上 {{url_for(‘func‘)}}

  4. 过滤器的基本使用

    • 有时候我们想要再模板中对一些变量进行处理,那么就必须需要类似于Python中的函数一样,可以将这个值传到函数中,然后做一些操作

    • 基本语法:

      • {{variable|过滤器名字}}。使用管道符号‘|‘进行组合

    • 过滤器是通过管道符号(|)进行使用的,列如{{name|length}},将返回name的长度。过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功能,再返回相应的值,之后再将结果渲染到页面中。Jinja2中内置了许多过滤器,再这里可以看到所有的过滤器,现在对一些常用的过滤器进行详解:

      • abs(value):返回一个数的绝对值 列如-1|abs

      • default(value,default_value,boolean=false):如果当前变量没有值e,则会使用参数中的值来代替。{{name|defaule(‘xiaotuo‘)}} --如果name不存在,则会使用xiaotuo来替代.boolean=False默认是再只有这个变量为undefined的时候才会使用default中的值,如果想使用python的形式判断是否为false(列如:None,空字符串,空列表,空字典等),则可以传递boolean=true

        • 也可以使用or来替代default(‘默认值‘,boolean=True).例如

          • {{singature or ‘此人很懒,没人留下说明‘}}

      • 自动转义过滤器:

        • escape(value)或e:转义字符. 会将< 、>等符号转义成HTML中的符号。列如:content|escape 或content|e

        • safe(value):如果开启了全局转义,那么safe过滤器会将变量关掉转义。示例:content_html|safe

        • autoescape标签,可以对他里面的代码块关闭或开启自动转义

          • {%autoescape off/on%} off是关闭自动转义 on是开启自动转义

          • .....代码块

          • {%endautoescape%}

      • first(value):返回一个序列的第一个元素。names|first

      • format(value,*args,**kwargs):格式化字符串。例如

        • {{"%s-%s"|format(‘hello?‘,"Foo!”)}} 将输出: hello?-Foo!

      • last(value):返回一个序列的最后一个元素。示例names|last

      • length(value):返回一个序列或者字典的长度。示例names|length

      • join(value,d=u"):将一个序列用d这个参数的值拼接成字符串

      • 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): 计算一个长字符串中单词的个数

    • 自定义模板过滤器

      • 过滤器本质上就是一个函数,如果在模板中调用这个过滤器,那么就会将这个变量的值作为第一个参数传给过滤器这个函数,然后函数的返回值会作为这个过滤器的返回值。需要使用到一个装饰器 @app.template_filter(‘cut‘)

      • 1.在python文件中,写好自己的过滤器。

        • @app.template_filter(‘cut‘) #装饰器里面传的我们自定义过滤器的名字,方便再HTML中使用

        • def cut(value): value是当再html中调用这个自定义过滤器的时候,会将调用这个自定义过滤器的变量传给value

          • value = value.replace(‘hello‘,‘‘)

          • return value

      • 2.在HTML中

        • < p>{{story|cut}} < /p>

  5. 控制语句详解

    • 所有的控制语句都是放在{%....%}中,并且有一个语句{%endxxx%}来进行结束.Jinja2中 常用的控制语句有if/for....in...,现对他们进行详解

      • 1.‘if‘: if语句和python中的类似,可以使用>,<,<=,>=,==,!=来进行判断,也可以通过‘and or not,()‘来进行逻辑合并操作,以下看列子

        • + {% if kenny.sick %}
            + kenny is sick.
          + {% elif kenny.dead %}
            + You killed Kenny! You bastard!!!
          + {%else%}
            + Kenny looks okay---so far
          + {%endif%}
      • 2.‘for....in...‘:‘for‘循环可以遍历任何一个序列包括数组、字典、元组。并且可以进行反向遍历。以下将用几个列子进行解释:

        • 普通的遍历

          • + < ul>
            + {%for user in usres%}
            + < li>{{user.username|e}} < /li>
            + {%endfor%}
            + < /ul>
        • 遍历字典:

          • + < dl>
            + {%for key,value in my_dice.iteritems() %}
            + < dt> {{key|e}}</ dt>
            + < dd> {{value|e}}< /dd>
            + {{%endfor%}}
            + < /dl>
        • 如果序列中没有值的时候,进入‘else‘

          • + < ul>
            + {%for user in usres%}
            + < li>{{user.username|e}} < /li>
            + {%else%}
            + < li>< em>no users found< /em>< /li>
            + {%endfor%}
            + < /ul>
        • 并且Jinja中的for循环还包含以下变量,可以用来获取当前的遍历状态:

          • 变量 描述

          • loop.index 当前迭代的索引(从1开始)

          • loop.index0 当前迭代的索引(从0开始)

          • loop.first 是否是第一次迭代,返回Ture或False

          • loop.last 是否是最后一次迭代,返回True或False

          • loop.length 序列的长度

        • 另外,不可以使用continue和break表达式来控制循环的执行

  6. 宏的使用

    • 宏的概念和基本使用

      • 模板中的宏跟python中的函数类似,可以传递函数,但是不能有返回值,可以将一些经常用到的代码片段放到宏中,然后把一些不固定的值抽取出,来当成一个变量,使用宏的时候,参数可以为默认值。以下将用一个列子来进行解释:

        • 定义宏

          • + {%macro input(name,value="",type=text)%}
              + < input type="{{type}}",name="{{name}}",value="{{value|e}}">
            + {%endmacro%}
      • 以上列子可以抽出了一个input标签,指定了一些默认参数。那么我们以后创建‘input‘标签的时候,可以通过她快速的创建

        • 使用宏

          • + < p>{{input(usename) }}< /p>
            + < p>{{input(password,type=password)  }} < /p>
    • import语句

      • 在真实的开发中,会将一些常用的宏单独放在一个文件中,在需要使用的时候,再从这个文件中进行导入。‘import‘语句的用法跟‘python‘中的‘import‘类似,可以直接‘import....as....‘,也可以 from....import.... 或者 from....import....as...,假设现在有一个文件,叫做forms.html,里面有两个宏分别为 input和textarea 如下

        • + {%macro input(name,value="",type=text)%}
            - < input type="{{type}}",name="{{name}}",value="{{value|e}}">
          + {%endmacro%}
          + {%macro textarea(name,value="",rows=10,cols=40)%}
            - < textarea name="{{name}}"  rows="{{rows}}" cols="{{cols}}">{{value|e}} < /textarea>
          + {%endmacro%}
      • 导入宏的列子

        • 宏文件路径,不要以相对路径去寻找,都要以‘templates‘作为绝对路径去找

        • 如果想要在导入宏的时候,就把当前模板的一些参数传给宏所在的模板,那么就应该在导入的时候使用with context 示例

          • from ‘xxx.html‘ import input with context

        • + 1.import....as....形式:
            + {%import forms.html as forms%}
            + < dl>
              + < dt>Username< /dt>
              + < dd>{{forms.input(username) }} < /dd>
              + < dt>Password< /dt>
              + < dd>{{forms.input(password,type=password) }} < /dd>
            + < /dl>
            + < p> {{forms.textarea(comment) }} < /p>
          + 2.from...import....as..../from....import...形式
            + {%from forms.html import  input as input_field,textarea %}
    • include标签

      • 这个标签相当于是直接将指定的模板代码复制粘贴到当前位置

      • ‘include‘标签,如果想要使用父模板中的变量,直接用就可以了,不需要使用with context

      • include的路径,也是跟import 一样,直接从‘templates‘根目录下去找,不要以相对路径去找

        • {%include ‘路径名.html‘%}

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

      • set语句:

        • 在模板中,可以使用‘set‘语句来定义变量,示例如下

          • {%set username=‘小鑫‘%}

          • 一旦定义了这个变量,那么在后面的代码中,都可以使用这个变量,就类似于python的变量定义是一样的

      • with语句:

        • with语句定义的变量,只能在‘with‘语句块中使用,超过了这个代码块,就不能在再使用了。示例代码块如下

          • + {%with classroom=xiaoxin1%}
            + < p> 班级: {{classroom}} < /p>
            + {%endwith%}
        • with语句也不一定要跟一个变量,可以定义一个空的‘with‘语句,以后再‘with’块中通过‘set‘定义的变量,就只能再这个‘with‘块中使用了

          • + {%with %}
            + {%set classroom=xiaoxin1%}
            + < p> 班级: {{classroom}} < /p>
            + {%endwith%}
    • 加载静态文件(图片、CSS、JS)

      • 1.加载静态文件使用的是url_for函数,然后第一个参数需要为‘static‘,第二个参数需要为一个关键字参数 ‘filename="路径" ‘ 示例:

        • {{url_for("static",filename="xxx") }}

      • 路径查找,要以当前项目的‘static’目录作为根目录

    • 模板继承详解

      • 为什么需要模板继承

        • 模板继承可以把一些公用的代码单独抽取出去放到一个父模板中,以后子模版直接继承就可以使用了,这样可以减少重复性的代码,并且以后修改起来也比较方便

      • 模板继承语法:

        • 使用‘extends关键语句‘,来指明继承的父模板。父模板的路径,也是相对于templates文件夹下的绝对路径。示例代码如下

          • {%extends ‘base.html‘%}

      • block语法:

        • 一般在父模板中,只能定义一些公用的代码。子模版可能要根据具体的需求实现不同的代码。这时候父模板就应该有能力提供一个接口,让子模板来实现,从而实现具体业务需求的功能。

        • 在父模板中

          •  {%block block的名字%}
            {%endblock%}
        • 在子模版中 也叫方法重写(重写父模板里面的block)

          • + {%block block的名字%}
            + 子模版中的代码
            + {%endblock%}
      • 调用父模板代码blcok中的代码

        • 默认情况下,子模版如果实现了父模板定义的block,那么子模版block中的代码就会覆盖掉父模板中的代码。如果想要在子模版中仍然保持父模板中的代码,那么可以使用{{super()}}来实现。 示例如下

          • 父模板

            • + {%block block的名字%}
              + 这是父模板里面的代码
              + {%endblock%}
          • 子模版

            • + {%block block的名字%}
              + {{super()}}
              + 这是子模版中的代码
              + {%endblock%}
      • 调用另外一个block中的代码

        • 如果想要在另外一个模板中使用其他模板中的代码,那么可以通过{{self.其他block名字()}} 就可以了 示例代码如下

          • + {%block title%}
            + 这是首页
            + {%endblock%}
            + 
            + {%block body_block%}
            + {{self.title()}}
            + 我是子模版中的代码
            + {%endblock%}
      • 其他注意事项

        • 1.子模版中的代码,第一行,应该是‘extends‘

        • 2.子模版中,如果想要实现自己的代码,应该放到block中,如果放到其他地方,那么就不会被渲染

以上是关于Flask模板jinja2的主要内容,如果未能解决你的问题,请参考以下文章

Flask模板

Flask Jinja2模板语言

Flask 入门教程:Jinja2模板用法

12. 爬虫训练场项目,jinja2 模板继承,项目继续迭代

Flask 入门教程:Jinja2模板用法

Jinja2模板引擎简介