• Flask(二)


    钩子函数

    from flask  import Flask

    app = Flask(__name__)

    # 第一次请求之前会来调用

    # 初始化操作

    @app.before_first_request

    def demo1():

          print("第一次请求会调用"")

    # 每次请求之前都会调用,应用场景:封装ip处理

    @app.before_request

    def demo2():

      print("每次请求之前会被调用")

    #每次请求之后都会调用这个钩子函数,应用场景:对response进行统一处理

    @app.after_request

    def demo3(response):

      # response.headers["Content-Type"] = "application/json"

      print("每次请求之后才会调用")

      return response

    # 每次都会执行,都会带入一个服务器的错误过来

    @app.teardown_request

    def demo4(err):

      print(err)

      print("每次请求之后都会调用一个服务器错误过来)

    if  __name__ == "_main__":

      app.run(debug=True)

    对cookie进行操作:

    from flask import Flask, make_response, request

    app = Flask(__name__)

    @app.route("/login")

    def login():

      """登录成功之后借助cookie保存用户登录信息"""

      # 创建响应对象

      response = make_response("login_success")

      # 借助响应对象的set_cookie方法设置键值对

      # 参数1:ke, 参数2:value, 参数3:max_age表示过期时长(以秒为单位)

      # set_cookie("key",值) Cookie是存储在浏览器中的一段纯文本

      response.set_cookie("user_name", "kangkang", max_age=3600)

      response.set_cookie("age", "18", max_age= 3600)

      return response

    # 获取cookie

    @app.route("/index")

    def index():

    """再次请求首页的时候,提起cookie中的用户信息"""

      user_name = request.cookies.get("user_name", "")

      age = request.cookies.get("age", "")

      return "index %s --- %s" %(user_name, age)

    # 删除cookie

    @app.route("/login_out")

    def login_out():

      response = make_response("login_out success")

      response.delete_cookie("user_name")

      response.delete_cookie("age")

      #将响应对象返回

      return response

    if __name__== "__main__":

      app.run(debug=True)

    对session进行操作,session依赖于cookie,服务器会返回一个session_id即为cookie,session里面包含用户信息

    from flask import Flask, session

    app = Flask(__name__)

    # session需要设置秘钥,可以写一个任意的字符串,两种写法,app.config是个字典

    app.config="2323242423"

    app.config["SECREY_KEY"] = "3213232"

    @app.route("/login")

    def login():

      # session将用户数据存储在服务器的内存中--redis数据库

      session["user_name"]= "kangkang"

      session["user_id"] = "12"

      return "login success"

    @app.route("/index")

    def index():

      user_name = session.get("user_name", "")

      user_id = session.get("user_id", "")

      return "index:%s ---%s" %(user_name, user_id)

    @app.route("/login_out")

    def login_out():

      session.pop("user_name", "")

      session.pop("age", "")

      return "login_out success"

    if __name__ == "__main__":

      app.run(debug=True)

    捕获异常:

    from flask import Flask, redirect, abort

    app = Flask(__name__)

    @app.route("/")

    def hello():

      a = 1/0

      abort(404)  # 主动产生一个404异常,abort需要先导入该库,abort传入的必须是http存在的错误状态码

      return "hello world"

    # 通过errorhandler捕获错误状态码

    @app.errorhandler(404)

    def handler(e):

      print(e)

      # 重定向到百度的错误页面链接

      return redirect("https://www.baidu.com/search/error.html")

    # 通过errorhandler捕获异常

    @app.errorhandler(ZeroDivisionError)

    def err(err):

      return "不能除以0"

    if __name__ == "__main__":

      app.run(debug=True)

    上下文:

    请求上下文: request和session

    应用上下文:current_app, g变量(flask程序全局的一个临时变量)

    from flask import Flask, request, session, current_app, g

    app =Flask(__name__)

    app.config["SECRECT_KEY"] = "avdvdvd"

    # print(request.method)  Working outside of request context.请求上下文超出范围

    # print(g.user) Working outside of request context.应用上下文超出范围

    # 只能在视图函数里面进行操作,在外部进行操作就会超出范围

    @app.route("/")

    def hello():

    # 请求上下文

      print(request.method)

      print(request.url)

      session["user_name"] = "curry"

      print(session.get("user_name", ""))

      # 应用上下文(current_app, g)

      print(current_app.config.get("DEBUG"))

      g.user = "james"

      print(g.user)

      return "hello world"

    if __name__ == "__main__":

      app.run(debug=True)

    • 请求上下文:保存了客户端和服务器交互的数据
    • 应用上下文:flask 应用程序运行过程中,保存的一些配置信息,比如程序名、数据库连接、应用信息等

    Flask-Script拓展

    需要安装Flask-Script拓展

    pip install flask-script

    from flask import Flask

    from flask_script import Manager

    app = Flask(__name__)

    manager= Manager(app)

    @app.route("/")

    def hello():

      return "hello world"

    if __name__ == "__main__":

      manager.run()

    通过终端命令: python XX.py runserver  -h ip地址 -p 端口号  -d

    同样也可以配置该文件的环境变量进行右键运行.

    Jinja2模板引擎简介

    视图函数的主要作用是生成请求的响应,这是最简单的请求。实际上,视图函数有两个作用:处理业务逻辑和返回响应内容。在大型应用中,把业务逻辑和表现内容放在一起,会增加代码的复杂度和维护成本。本节学到的模板,它的作用即是承担视图函数的另一个作用,即返回响应内容。

    • 模板其实是一个包含响应文本的文件,其中用占位符(变量)表示动态部分,告诉模板引擎其具体的值需要从使用的数据中获取
    • 使用真实值替换变量,再返回最终得到的字符串,这个过程称为“渲染”
    • Flask是使用 Jinja2 这个模板引擎来渲染模板

    使用模板的好处:

    视图函数只负责业务逻辑和数据处理(业务逻辑方面)

    而模板则取到视图函数的数据结果进行展示(视图展示方面)

    代码结构清晰,耦合度低

    Jinja2:是 Python 下一个被广泛应用的模板引擎,是由Python实现的模板语言,他的设计思想来源于 Django 的模板引擎,并扩展了其语法和一系列强大的功能,其是Flask内置的模板语言。

    模板语言:是一种被设计来自动生成文档的简单文本格式,在模板语言中,一般都会把一些变量传给模板,替换模板的特定位置上预先定义好的占位变量名

    Flask提供的 render_template 函数封装了该模板引擎

    render_template 函数的第一个参数是模板的文件名,后面的参数都是键值对,表示模板中变量对应的真实值

    {{}}来表示变量名,这种{{}}语法叫做代码块变量, {{{position.title}}

    Jinja2模板中的变量代码块可以是任意Python类型或者对象,只要它能够Python的Str()方法转换为一个字符串就可以,

    {{your_dict['key']}}

    {{your_list[0]}}

    用{% %}定义的控制代码块,可以实现一些语言层次的功能,比如循环或if语句

    {% if user %}

      {{user}}

    {% else %}

      hello!

    <ul>

      {% for index in indexs %}

        <li>{{index}}</li>

        {% endfor %}

    </ul>

    使用{# #}进行注释,注释的内容不会再html中被渲染出来

    模板的基本使用:

    在项目下创建templates文件夹,用于存放所有的模板文件,并在目录下创建一个模板html文件

    from flask import Flask, render_template

    app = Flask(__name__)

    @app.route("/")

    def index():

      myint = 18

      mystr = "curry"

      my_list =[1, 23,4,6,5]

      my_dict = {

      "name":"duan",

      "age":28

      }

      return render_template("dem01.html",

                 myint = myint, mystr = mystr, my_dict=my_dict, my_list = my_liust)

    if __name == "__main__":

      app.run()

    对应的demo01.html:

    <!DOCTYPE html>

    <html lang="en">

    <head>

       <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    我的模板html内容
    <br/>{{ my_str }}
    <br/>{{ my_int }}
    <br/>{{ my_array }}
    <br/>{{ my_dict }}

    </body> </html>

    链式调用: {{"hello world" | reverse | upper}}

    常见内建过滤器:

    字符串操作

    safe:禁止转义 {{"<em>hello</em>"| safe}}

    capitalize:把变量的首字母转成大写,其余字母小写 {{'hello" | capitalize}}

    lower:把值转成小写, {{"HELLO" | lower}}

    upper:把值转成大写,{{"hello" | upper}}

    title:把每个单词的首字母都转成大写, {{'he is girl" | title}}

    reverse:字符串反转,

    format:格式化输出 {{'%s is %d' | format('name', 7)}}

    striptags:把html中的tag去掉, {{'<h1>hello</h1>" | striptags}}

    truncate:字符串截断 {{'hello every one" | truncate(9) }}

    列表操作

    list=[1,2,3,1,2,3,6,8,4]

    first :取第一个元素 {{list | first}}

    last:取最后一个元素{{list | last}}

    length:获取列表长度{{list | length}}

    sum:求列表的和{{list | sum}}

    sort:列表排序 {{list | sort}}

    语句块过滤:

    {% filter upper %}

     # 一大堆文字#

    {% endfilter %}

    自定义过滤函器

    from flask import render_template, Flask

    app = Flask(__name__)

    # 方法一:自定义列表反函数

    @app.template_filter("list_reverse")

    def list_rever(list):

      list.reverse()

      return list

    # 方式二:将自定义的函数添加到flask过滤器中,add_template_filter(函数名, "创建过滤器名称") 函数名不需要打引号

    app.add_template_filter(list_rever, "list_reverse")

    @app.route("/")

    def index():

      list = [1,2,3,4,6,5]

      return render_template("demo02.html", list = list)

    if __name__ == "__main__":

       app.run(debug=True)

    demo02.html内容:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    自定义过滤器<hr>
    <body>
    {{ list }}
    <br>
    {{ list | list_reverse }}
    </body>
    </html>

     控制代码:

    from flask import Flask, render_template

    app = Flask(__name__)

    @app.route("/")

    def index():

      # 只显示四行数据, 并设置颜色

      my_list = [

        

    {
    "id":1,
    "value":"我爱代码"
    },
    {
    "id": 2,
    "value": "代码使人快乐"
    },
    {
    "id": 3,
    "value": "沉迷于代码无法自拔"
    },
    {
    "id": 4,
    "value": "日渐消瘦"
    },
    {
    "id": 5,
    "value": "以梦为马,越骑越傻"
    }

    ]

    return render_template("demo03.html", my_list = my_list)

    if __name__ == "__main__":

      app.run(debug=True)

    demo03.html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    控制代码块<hr>
    {% for item in my_list%}
    {# {% if item.id != 5 %}#}
    {% if loop.index == 1 %}
    <li style="background-color: yellow">{{ item.value }}</li>
    {% elif loop.index == 2%}
    <li style="background-color: #2aabd2">{{ item.value }}</li>
    {% elif loop.index == 3 %}
    <li style="background-color: #2b542c">{{ item.value }}</li>
    {% elif loop.index == 4 %}
    <li style="background-color: #8a6d3b">{{ item.value }}</li>
    {% elif loop.index == 5 %}
    <li style="background-color: darkgrey">{{ item.value }}</li>

    {% endif %}

    {# {% endif %}#}


    {% endfor %}


    loop.index: 当前循环迭次的次数(从1开始)

    loop.index0:当前循环迭代的次数(从0开始)

    loop.revindex: 到循环结束需要迭的次数(从1开始)

    loop.revindex0:到循环结束需要迭代的次数(从0开始)

    loop.first 第一迭代,为True

    loop.last 最后一次迭代,为True

    loop.length  序列中的项目数

    loop.cycle:在一串序列期间取值的辅助函数.

    模板继承:

    在模板中,可能会遇到以下情况:

    • 多个模板具有完全相同的顶部和底部内容
    • 多个模板中具有相同的模板代码内容,但是内容中部分值不一样
    • 多个模板中具有完全相同的 html 代码块内容

    像遇到这种情况,可以使用 JinJa2 模板中的 继承 来进行实现

    from flask import Flask, render_template

    app = Flask(__name__)

    @app.route("/parent")

    def parent():

      return render_template("base.html")

    @app.route("/child")

    def child():

      return render_template("child.html")

    if __name__ == "__main__":

      app.run(debug=True)

    base.html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    {# 把要重写的父类的内容用{% block 名称x %} XXX {% endblock %}#}
    {% block testA %}
    <h2>父类模板<h2>
    {% endblock %}
    <h2>父类内容</h2>
    <h2>父类底部</h2>

    <body>

    </body>
    </html>

    child.html内容:

    {# 子类继承父类使用extends关键字 {% extends  '父类.html'  %}#}

    {% extends "base.html'' %}

    {# 重写父类中的部分内容#}

    {# 不丢失父类原有的内容使用super()#}

    {% block testA % }

    {{super()}}

    <h2>我是子类模板</h2>

    {% endblock %}

    怎样设置templates的html文件在使用render_template方法时自动弹出里面的html文件进行选择

    选择Jinja2,apply之后点击ok即可

    可以设置自己设置状态码及状态码解释

    from flask import Flask

    app = Flask(__name__)

    @app.route("/")

    def index():

      # 666代表状态码, 解释为状态码的解释信息

      return "hello world", "666 解释"

    if __name__ == "__main__":

      app.run(debug=True)

  • 相关阅读:
    线程池。
    等待唤醒机制。
    第一册:lesson 131.
    线程同步机制。
    第一册: lesson 129。
    线程实现方式。
    第一册:lesson 125.
    第一册:Lesson 123.
    黄渤的谈话。
    K3 KFO 手册
  • 原文地址:https://www.cnblogs.com/zhouzetian/p/9683550.html
Copyright © 2020-2023  润新知