• Flask 基础组件(四):模板


    1、模板的使用

    1.1  语法

    1.1.1 流程控制

    逻辑语法

    Jinja2模板语言中的 for

    {% for foo in g %}
    
    {% endfor %}

    Jinja2模板语言中的 if

    复制代码
    {% if g %}
    
    {% elif g %}
        
    {% else %}
        
    {% endif %}

    1.1.2 变量#

    {{}} 

    1.2 实例

    数据准备

    后端定义几个字符串,用于传递到前端

    复制代码
    STUDENT = {'name': 'Old', 'age': 38, 'gender': '中'},
    
    STUDENT_LIST = [
        {'name': 'Old', 'age': 38, 'gender': '中'},
        {'name': 'Boy', 'age': 73, 'gender': '男'},
        {'name': 'EDU', 'age': 84, 'gender': '女'}
    ]
    
    STUDENT_DICT = {
        1: {'name': 'Old', 'age': 38, 'gender': '中'},
        2: {'name': 'Boy', 'age': 73, 'gender': '男'},
        3: {'name': 'EDU', 'age': 84, 'gender': '女'},
    }

    1.2.1. 使用STUDENT字典传递至前端#

    前端页面

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <table border="1px">
        <thead>
            <tr>
                <th>姓名</th>
                <th>年龄</th>
                <th>性别</th>
            </tr>
        </thead>
        <tbody>
            {% for foo in stu %}
                <tr>
                    <td>{{ foo.name }}</td>
                    <td>{{ foo.age }}</td>
                    <td>{{ foo.gender }}</td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
    </body>
    </html>
    复制代码

    后端代码

    复制代码
    from flask import Flask,render_template,request
    app = Flask(__name__)
    STUDENT = {'name': 'Old', 'age': 38, 'gender': '中'},
    
    @app.route('/login',methods=["POST","GET"])
    def login():
        if request.method == "GET":
            return render_template("login.html",stu=STUDENT)
    
    if __name__ == '__main__':
        app.run("0.0.0.0", 9876)
    复制代码

    1.2.2. STUDENT_LIST 列表传入前端Jinja2 模板的操作

    前端页面

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <table border="1px">
        <thead>
            <tr>
                <th>姓名</th>
                <th>年龄</th>
                <th>性别</th>
            </tr>
        </thead>
        <tbody>
            {% for foo in stu %}
                <tr>
                    <td>{{ foo.get("name") }}</td>
                    <td>{{ foo.age }}</td>
                    <td>{{ foo["gender"] }}</td>
                </tr>
            {% endfor %}
    
        </tbody>
    </table>
    
    </body>
    </html>
    复制代码

    上面我们用了三种取值方式,这里foo就是每个字典

    后端代码

    复制代码
    from flask import Flask,render_template,request
    app = Flask(__name__)
    
    STUDENT_LIST = [
        {'name': 'Old', 'age': 38, 'gender': '中'},
        {'name': 'Boy', 'age': 73, 'gender': '男'},
        {'name': 'EDU', 'age': 84, 'gender': '女'}
    ]
    
    @app.route('/login',methods=["POST","GET"])
    def login():
        if request.method == "GET":
            return render_template("login.html",stu=STUDENT_LIST)
    
    if __name__ == '__main__':
        app.run("0.0.0.0", 9876)
    复制代码

    1.2.3 STUDENT_DICT 大字典传入前端 Jinja2 模板#

     前端页面

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <table border="1px">
        <thead>
            <tr>
                <th>序号</th>
                <th>姓名</th>
                <th>年龄</th>
                <th>性别</th>
            </tr>
        </thead>
        <tbody>
            {% for foo in stu %}
                <tr>
                    <td>{{ foo }}</td>
                    <td>{{ stu.get(foo).name }}</td>
                    <td>{{ stu.get(foo).age }}</td>
                    <td>{{ stu.get(foo).gender }}</td>
    
                </tr>
            {% endfor %}
    
        </tbody>
    </table>
    
    </body>
    </html>
    复制代码

    后端代码

    复制代码
    from flask import Flask,render_template,request
    app = Flask(__name__)
    
    STUDENT_DICT = {
        1: {'name': 'Old', 'age': 38, 'gender': '中'},
        2: {'name': 'Boy', 'age': 73, 'gender': '男'},
        3: {'name': 'EDU', 'age': 84, 'gender': '女'},
    }
    @app.route('/login',methods=["POST","GET"])
    def login():
        if request.method == "GET":
            return render_template("login.html",stu=STUDENT_DICT)
    
    if __name__ == '__main__':
        app.run("0.0.0.0", 9876)
    复制代码

    在遍历字典的时候,foo 其实是相当于拿出了字典中的Key

     

    1.2.4 Markup#

    该方法和django中的safe一样都是防止xss攻击、

    复制代码
    from flask import Flask,render_template,request
    from markupsafe import Markup
    
    app = Flask(__name__)
    
    @app.route('/login',methods=["POST","GET"])
    def login():
        if request.method == "GET":
            my_in = Markup("<input type='text' name='uname'>")
            return render_template("login.html",ss=my_in)
    
    if __name__ == '__main__':
        app.run("0.0.0.0", 9876)
    复制代码

    前端页面生成的标签:

    <input type="text" name="uname">

     1.4 模板继承

    模板继承语法:

    使用‘extend’语句,来指明继承的父模板。

    示例代码:

    {% extends 'base.html' %}

    block语法:

    一般在父模版中,定义一些公共的代码。子模版可能要根据具体的需求实现不同的代码。

    这时候父模版就应该提供一个接口,让父模版来实现。从而实现具体业务需求的功能。

    在父模版中:

    {% block block的名字 %}
    {% endblock %}

    在子模版中:

    {% extends 'base.html' %}
    {% block body_block %}
        子模板代码
    {% endblock %}

    调用父模版的代码block中的代码:

    默认情况下,子模版如果实现了父模版定义的block,那么子模版block中的代码就会覆盖掉父模版中的代码,如果想在子模版中仍然保持父模版代码,需要用super() 函数调用。具体代码如下:

    {% block body_block %}
        {{ super() }}    {#super()调用父模版代码#}
        <p style="background-color: green;">首页子模板代码</p>
    {% endblock %}

    调用另一个block中的代码:

    一个模板中使用其他模板的代码。那么可以通过'{{ self.其他block名字() }}'

    示例代码如下:

    {% block another_block %}
        我是另一个模板的代码
    {% endblock %}
    {% block body_block %}
        {{ self.another_block() }}
        <p style="background-color: green;">首页子模板代码</p>
    {% endblock %}

    其他注意事项:

    1. 子模版中的代码,第一行应该是继承的代码。'extends'.

    2. 子模版中,如果要实现自己的代码,应该放到block中,如果放到外面,将无法被渲染。

    2、自定义模板方法

    Flask中自定义模板方法的方式和Bottle相似,创建一个函数并通过参数的形式传入render_template,如:

    #login.html
    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <h1>自定义函数</h1>
        {{ww()|safe}}
    
    </body>
    </html>
    
    html
    # run.py
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from flask import Flask,render_template
    app = Flask(__name__)
     
     
    def wupeiqi():
        return '<h1>Wupeiqi</h1>'
     
    @app.route('/login', methods=['GET', 'POST'])
    def login():
        return render_template('login.html', ww=wupeiqi)
     
    app.run()

    其他

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    
        {% macro input(name, type='text', value='') %}
            <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
        {% endmacro %}
    
        {{ input('n1') }}
    
        {% include 'tp.html' %}
    
        <h1>asdf{{ v.k1}}</h1>
    </body>
    </html>

    过滤器

    使用方式: 变量名|过滤器

    {{variable | filter_name(*args)}}

    如果没有任何参数传给过滤器,则可以把括号省略掉
    在 jinja2 中,过滤器是可以支持链式调用的,

    示例如下{{ "hello world" | reverse | upper }}

    flask自带的过滤器

    字符串操作
    禁用转义: {{ '<em>hello</em>' | safe }}
    删除标签: {{ '<em>hello</em>' | striptags }}
    首字母大写: {{ 'hello' | capitalize }}
    所有值小写: {{ 'HELLO' | lower }}
    首字母大写: {{ 'hello world' | title }}
    字符串反转: {{ 'hello' | reverse }}
    字符串截断: {{ 'hello world' | truncate(5) }}

    列表操作
    获取列表长度: {{ [1,2,3,4,5,6] | length }}
    列表求和: {{ [1,2,3,4,5,6] | sum }}
    列表排序: {{ [6,2,3,1,5,4] | sort }}

    自定义过滤器

    方式一:

    通过Flask应用对象的add_template_filter方法

    def list_reverse(li):
        temp = list(li)
        temp.reverse()
        return temp
    
    # 可以给过滤器器一个名字,如果没有,默认就是函数的名字
    app.add_template_filter(list_reverse,'li_reverse')
    方式二:

    通过装饰器来实现自定义过滤器

    # 使用装饰器事项过滤器,
    # 如果不传入参数,默认过滤器名字就是函数的名字    
    @app.template_filter()
    def my_filter(args):
        temp = list(args)
        temp.reverse()
        return temp
    在html模板中调用过滤器:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>jinjia2模板测试</title>
    </head>
    <body>
        <h1>len: {{ [1,2,3,4,5,6] | length }}</h1>   #此处调用上文flask自带的过滤器
        <h1> {{ [1,2,3,4,5,6] | my_filter }}</h1>   #此处调用上文自定义过滤器
      
    </body>
    </html>
     

    xss,csrf,json 攻击

    https://www.cnblogs.com/shengulong/p/7693107.html

    {{variable | filter_name(*args)}}
    

    如果没有任何参数传给过滤器,则可以把括号省略掉
    在 jinja2 中,过滤器是可以支持链式调用的,示例如下

    {{ "hello world" | reverse | upper }}


    作者:Gavininn
    链接:https://www.jianshu.com/p/1ae7d2c3c223
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    AS400一些有用的命令
    Publish的时候某些需要用到的文件没deploy上去
    DB2一些SQL的用法
    根据PostgreSQL 系统表查出字段描述
    linux memcached 安装
    CentOS下XEN虚拟服务器安装配置
    Apache the requested operation has failed
    PHP配置兼容ZendDebugger和Optimizer
    虚拟机比较
    memcache 运行情况,内存使用
  • 原文地址:https://www.cnblogs.com/qiu-hua/p/12813236.html
Copyright © 2020-2023  润新知