python -- (Flask简介) --(四)

本文详细介绍了Flask框架中的模板功能,包括如何创建视图函数进行模板渲染,模板中的过滤器及其自定义,控制代码块如if/else,宏的使用,模板继承的概念和注意事项,以及包含、特殊变量和函数的应用。同时,文章还讨论了防止CSRF攻击的方法,强调了在表单提交中验证csrf_token的重要性。
摘要由CSDN通过智能技术生成

1. 模板

  • 在项目下创建 templates 文件夹,用于存放所有的模板文件
创建视图函数,进行模板渲染
from flask import Flask, render_template

app = Flask(__name__)


@app.route('/')
def index():
    return 'index'


@app.route('/demo1')
def demo1():

    my_int = 10
    my_str = "哈哈"
    my_list = [1, 4, 7, 9 ,6]
    my_dict = {
        "id": 1,
        "name": "laowang"
    }

    return render_template('template.html',
                           my_int=my_int,
                           my_str=my_str,
                           my_list=my_list,
                           my_dict=my_dict
                           )


if __name__ == '__main__':
    app.run(debug=True)
html中模板
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

{{ my_str }}<br/>
{{ my_int }}<br/>
{{ my_list }}<br/>
{{ my_dict }}<br/>

取值<br/>
{{ my_dict['name'] }}<br/>
{{ my_dict.id }}<br/>
{{ my_list[0] }}<br/>
{{ my_list.0 }}<br/>

计算<br/>
{{ my_int + my_list.1 }}<br/>

</body>
</html>
运行效果

在这里插入图片描述

2. 过滤器

from flask import Flask, render_template

app = Flask(__name__)


@app.route('/')
def index():
    return 'index'


@app.route('/demo1')
def demo1():

    my_int = 10
    my_str = "<h1>我是大标题</h1>"
    my_list = [1, 4, 7, 9, 6]
    my_dict = {
        "id": 1,
        "name": "laowang"
    }
    my_dict_list = [
        {
            "good_name": "大白菜",
            "price": 18
        },
        {
            "good_name": "白罗卜",
            "price": 10
        }
    ]

    return render_template('template.html',
                           my_int=my_int,
                           my_str=my_str,
                           my_list=my_list,
                           my_dict=my_dict,
                           my_dict_list=my_dict_list
                           )


if __name__ == '__main__':
    app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

{{ my_str }}<br/>
{{ my_int }}<br/>
{{ my_list }}<br/>
{{ my_dict }}<br/>

取值<br/>
{{ my_dict['name'] }}<br/>
{{ my_dict.id }}<br/>
{{ my_list[0] }}<br/>
{{ my_list.0 }}<br/>

计算<br/>
{{ my_int + my_list.1 }}<br/>

<hr>

{{ 'hello' | upper }}<br/>
{{ 'HELLO' | lower }}<br/>
{{ 'hello' | reverse }}<br/>
{# flask特有的 #}
{{ 'hello' | reverse | upper }}

列表过滤器:<br/>
{{ my_list | last }}<br/>
长度:{{ my_list | length }}<br/>
排序:{{ my_list | sort }}<br/>

<hr>
html的显示<br/>
{{ my_str }}
按html显示 {{ my_str | safe }}
默认html的字符串会按照原样显示,可以使用 safe 进行标识该字符串是安全的
如果使用safe标识该字符串是安全的话,那么就会按照html语言格式进行显示或者执行

<br/>
<hr/>
使用过滤器传参数<br/>
总价: {{ my_dict_list | sum(attribute='price') }}

</body>
</html>

3. 自定义过滤器

当模板内置的过滤器不能满足需求,可以自定义过滤器。自定义过滤器有两种实现方式:

  • 一种是通过Flask应用对象的 add_template_filter 方法
  • 通过装饰器来实现自定义过滤

重要:自定义的过滤器名称如果和内置的过滤器重名,会覆盖内置的过滤器。

通过调用应用程序实例的 add_template_filter 方法实现自定义过滤器。该方法第一个参数是函数名,第二个参数是自定义的过滤器名称:

def do_listreverse(li):
    # 通过原列表创建一个新列表
    temp_li = list(li)
    # 将新列表进行返转
    temp_li.reverse()
    return temp_li

app.add_template_filter(do_listreverse,'lireverse')

用装饰器来实现自定义过滤器。装饰器传入的参数是自定义的过滤器名称:

@app.template_filter('lireverse')
def do_listreverse(li):
    # 通过原列表创建一个新列表
    temp_li = list(li)
    # 将新列表进行返转
    temp_li.reverse()
    return temp_li

4.控制代码块

控制代码块主要包含两个:

  • if/else if /else / endif
  • for / endfor
    *在一个 for 循环块中你可以访问这些特殊的变量:
    在这里插入图片描述
from flask import Flask, render_template

app = Flask(__name__)


@app.route('/')
def index():
    return 'index'


@app.route('/demo1')
def demo1():

    # 只显示4行数据,背景颜色依次为:黄,绿,红,紫
    my_list = [
        {
            "id": 1,
            "value": "我爱工作"
        },
        {
            "id": 2,
            "value": "工作使人快乐"
        },
        {
            "id": 3,
            "value": "沉迷于工作无法自拔"
        },
        {
            "id": 4,
            "value": "日渐消瘦"
        },
        {
            "id": 5,
            "value": "以梦为马,越骑越傻"
        }
    ]

    return render_template('control.html', my_list=my_list)


if __name__ == '__main__':
    app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

{% for item in my_list if item.id != 5 %}
    {% if loop.index == 1 %}
        <li style="background-color: orange">{{ item.value }}</li>
    {% elif loop.index == 2 %}
        <li style="background-color: green">{{ item.value }}</li>
    {% elif loop.index == 3 %}
        <li style="background-color: red">{{ item.value }}</li>
    {% else %}
        <li style="background-color: purple">{{ item.value }}</li>
    {% endif %}
{% endfor %}


</body>
</html>

5. 宏

对宏(macro)的理解:

  • 把它看作 Jinja2 中的一个函数,它会返回一个模板或者 HTML 字符串
  • 为了避免反复地编写同样的模板代码,出现代码冗余,可以把他们写成函数以进行重用
  • 需要在多处重复使用的模板代码片段可以写入单独的文件,再包含在所有模板中,以避免重复
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body><form>
    <label>用户名:</label><input type="text" name="username"><br/>
    <label>身份证号:</label><input type="text" name="idcard"><br/>
    <label>密码:</label><input type="password" name="password"><br/>
    <label>确认密码:</label><input type="password" name="password2"><br/>
    <input type="submit" value="注册">
</form>

<hr>
使用宏实现

{% macro input(label="", type="text", name="", value="") %}
<label>{{ label }}</label><input type="{{ type }}" name="{{ name }}" value="{{ value }}">
{% endmacro %}

<form>
    {{ input("用户名:", name="username") }}<br/>
    {{ input("身份证号:", name="idcard") }}<br/>
    {{ input("密码:", type="password", name="password") }}<br/>
    {{ input("确认密码:", type="password", name="password2") }}<br/>
    {{ input(type="submit", value="注册") }}
</form>

</body>
</html>

6. 模板继承

模板继承是为了重用模板中的公共内容。

  • 标签定义的内容
{% block top %} {% endblock %}
  • 相当于在父模板中挖个坑,当子模板继承父模板时,可以进行填充
  • 子模板使用 extends 指令声明这个模板继承自哪个模板
  • 父模板中定义的块在子模板中被重新定义,在子模板中调用父模板的内容可以使用super()
父模板
  • base.html
{% block top %}
  顶部菜单
{% endblock top %}

{% block content %}
{% endblock content %}

{% block bottom %}
  底部
{% endblock bottom %}
子模板
  • extends指令声明这个模板继承自哪
{% extends 'base.html' %}
{% block content %}
 需要填充的内容
{% endblock content %}
  • 模板继承使用时注意点:
    • 不支持多继承
    • 在子模板中使用extends时,尽量写在模板的第一行
    • 不能在一个模板文件中定义多个相同名字的block标签
    • 当在页面中使用多个block标签时,建议给结束标签起个名字,当多个block嵌套时,阅读性更好。

7.包含

将另一个模板整个加载到当前模板中,并直接渲染。

  • include的使用
{% include 'hello.html' %}
  • include 的使用加上关键字ignore missing
{% include 'hello.html' ignore missing %}

8. 模板中特有的变量和函数

  • config
{{config.DEBUG}}
  • request
{{request.url}}
  • session
{{session.name}}
  • g变量
{{ g.name }}
  • url_for()
# url_for会根据传入的路由器函数名,返回该路由对应的URL,在模板中始终使用url_for()就可以安全的修改路由绑定的URL,则不比担心模板中渲染出错的链接
{{url_for('index')}}

# /
# 如果我们定义的路由URL是带有参数的,则可以把它们作为关键字参数传入url_for(),Flask会把他们填充进最终生成的URL中:
{{ url_for('post', post_id=1)}}

# /post/1
  • get_flashed_messages()
# 这个函数会返回之前在flask中通过flask()传入的消息的列表,flash函数的作用很简单,可以把由Python字符串表示的消息加入一个消息队列中,再使用get_flashed_message()函数取出它们并消费掉:
{%for message in get_flashed_messages()%}
    {{message}}
{%endfor%}

9. CSRF(跨站请求伪造)

在这里插入图片描述

防止 CSRF 攻击

  • 在客户端向后端请求界面数据的时候,后端会往响应中的 cookie 中设置 csrf_token 的值
  • 在 Form 表单中添加一个隐藏的的字段,值也是 csrf_token
  • 在用户点击提交的时候,会带上这两个值向后台发起请求
  • 后端接受到请求,以会以下几件事件:
    • 从 cookie中取出 csrf_token
    • 从 表单数据中取出来隐藏的 csrf_token 的值
    • 进行对比
  • 如果比较之后两值一样,那么代表是正常的请求,如果没取到或者比较不一样,代表不是正常的请求,不执行下一步操作
    ---------------------------------------------------END-----------------------------------------------
    ---------------------------------------------------END-----------------------------------------------
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值