• flask 安装与启动 路由视图 响应 请求 Jinjia2 Session


    1Python 现阶段三大主流Web框架 Django Tornado Flask 对比

    1.Django 主要特点是大而全,集成了很多组件,例如: Models Admin Form 等等, 不管你用得到用不到,反正它全都有,属于全能型框架

    2.Tornado 主要特点是原生异步非阻塞,在IO密集型应用和多任务处理上占据绝对性的优势,属于专注型框架

    3.Flask 主要特点小而轻,原生组件几乎为0, 三方提供的组件请参考Django 非常全面,属于短小精悍型框架

    Django 通常用于大型Web应用由于内置组件足够强大所以使用Django开发可以一气呵成

    Tornado 通常用于API后端应用,游戏服务后台,其内部实现的异步非阻塞真是稳得一批

    Flask 通常应用于小型应用和快速构建应用,其强大的三方库,足以支撑一个大型的Web应用

    Django 优点是大而全,缺点也就暴露出来了,这么多的资源一次性全部加载,肯定会造成一部分的资源浪费

    Tornado 优点是异步,缺点是干净,连个Session都不支持

    Flask 优点是精悍简单,缺点是你不会!哈哈哈哈哈哈!

    2Flask 的安装与HelloWorld

    安装

    pip install Flask

    Jinja2  模板语言

    Flask  源码

    MarkupSafe   处理标签语言   (比如处理 render_template)

    Werkzeug  工具  承载Flask 程序

    走一个

    #  导入Flask类
    from flask import Flask
    
    # 实例化Flask 对象 app
    app = Flask(__name__)
    
    
    # app中的route装饰器
    @app.route("/")
    # 视图函数
    def index():
        return "you jump  i jump"
    
    
    app.run("0.0.0.0", 5000)

    3Flask 中的 Render    Redirect   HttpResponse

    from flask import Flask, render_template, redirect, jsonify, send_file

    app = Flask(__name__)


    # 在Flask 中的HttpResponse 在我们看来其实就是直接返回字符串
    @app.route("/")
    def index():
    return "hello"


    # 如果要使用 render_template 返回渲染的模板,请在项目的主目录中加入一个目录 templates
    @app.route("/home")
    def home():
    return render_template("home.html")


    @app.route("/redi")
    def redi():
    return redirect("/home")

    #json类型
    @app.route("/json")
    def my_json():
    return jsonify({"a": 12})
    # return {"b":3}

    #文件类型
    @app.route("/file")
    def my_file():
    return send_file("1.png")


    app.run("0.0.0.0", 5000)

    Flask 中的返回特殊封装 2个
    1.jsonify 转换标准JSON格式
    响应头中加入 Content-type:application/json
    在Flask 1.1.1 版本中 加入了 直接返回字典 可以不再使用jsonify了

    2.send_file 发送文件
    打开并返回文件内容,
    自动识别文件类型,
    响应头中加入Content-type:文件类型
    ps:当浏览器无法识别Content-type时,会下载文件

    3Flask 中的 Request

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form action="" method="post"  enctype="multipart/form-data"> #发送文件用enctype
        用户名:<input type="text" name="username">
        密码:<input type="password" name="password">
        <input type="file" name="myfile">
        <input type="submit" value="提交">
    
    </form>
    
    
    </body>
    </html>

    request.args 与 request.form 的区别就是:

      request.args 是获取url中的参数

      request.form 是获取form表单中的参数

     request.values 之 只要是个参数我都要

    from flask import Flask, request, render_template
    
    app = Flask(__name__)
    
    # debug 模式可以自动刷新
    # app.debug=True
    app.config['DEBUG'] = True
    
    
    @app.route("/login", methods=["GET", "POST"])
    def login():
        if request.method == "GET":
            # print(request.url)  #获取访问路径   http://192.168.16.60:5000/login
            # print(request.method) #获取请求方式   GET
            # print(request.path)  # 路由地址   /login
            #
            # print(request.values)  # 可以获取URL中的参数 也可以获取 FormData中的数据
            # # CombinedMultiDict([ImmutableMultiDict([('id', '1')]), ImmutableMultiDict([])])
            
         # print(request.args.
    get("id")) # 获取URL中的参数 # print(request.args["id"]) # 获取URL中的参数 # print(request.args.to_dict()) # 获取URL中的参数 转换成 字典 # # print(request.environ) # 获取请求原始信息 # print(request.base_url) # 获取URL头,不包含参数 # # print(request.json) # 1 请求头中 Content-type:application/json 数据序列化 request.json # print(request.data) # 2 请求头中 Content-type 无法被识别 或者是没有 Form # # print(request.headers) # 请求头中的数据 return render_template("login.html") if request.method == "POST": # 两种方法 username = request.form.get("username") password = request.form["password"]
          #相当于django 中 request.POST.get() == request.form.get() -> .to_dict()
              #request.GET.get() == request.args.get() -> .to_dict()
        
    
            # print(request.form)  # ImmutableMultiDict([('username', 'aaa'), ('password', '111')])
            # print(request.values.to_dict())
            # print(request.form.to_dict()) #{'username': 'aaa', 'password': '111'}
    
            print(request.files.get("myfile"))  # <FileStorage: '1.png' ('image/png')>
            myfile = request.files.get("myfile")
            myfile.save(myfile.filename)
    
            if username == "aaa" and password == "123":
                return "登录成功"
            else:
                return "登录失败"
    
    
    app.run("0.0.0.0", 5000)

    4Flask 中的Jinja2

    from flask import Flask, render_template
    
    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': ''},
    }
    
    app = Flask(__name__)
    
    
    @app.route("/student")
    def index():
        return render_template("student.html", student=STUDENT,
                               student_list=STUDENT_LIST,
                               student_dict=STUDENT_DICT,
                               )
    
    
    if __name__ == '__main__':
        app.run()
    后端
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    
    </head>
    <body>
    
    {{ student }}
    <table border="1px">
        <thead>
        <tr>
            <th>name</th>
            <th>age</th>
            <th>gender</th>
        </tr>
        </thead>
        <tbody>
        <tr>
            <td>{{ student.name }}</td>
            <td>{{ student["age"] }}</td>
            <td>{{ student.get("gender") }}</td>
        </tr>
        </tbody>
    </table>
    
    {{ student_list }}
    <table border="1px">
        <thead>
        <tr>
            <th>name</th>
            <th>age</th>
            <th>gender</th>
        </tr>
        </thead>
        <tbody>
        {% for student in student_list %}
            <tr>
                <td>{{ student.name }}</td>
                <td>{{ student["age"] }}</td>
                <td>{{ student.get("gender") }}</td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
    
    {{ student_dict }}
    <table border="1px">
        <thead>
        <tr>
            <th>id</th>
            <th>name</th>
            <th>age</th>
            <th>gender</th>
        </tr>
        </thead>
        <tbody>
        {% for id,student in student_dict.items() %}
            <tr>
                <td>{{ id }}</td>
                <td>{{ student.name }}</td>
                <td>{{ student["age"] }}</td>
                <td>
                    {% if student["gender"] !="" and  student["gender"] !="" %}
                        女
                    {% else %}
                        {{ student.get("gender") }}
                    {% endif %}
                </td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
    
    </body>
    </html>
    前端

    safe  两种方法  1 改前端 {{ tag | safe}}

           2改后端    markup_tag = Markup(tag)

    执行python 函数
    #  导入Flask类
    from flask import Flask, render_template, Markup
    
    app = Flask(__name__)
    
    
    def ab_sum(a, b):
        return a + b
    
    
    @app.route("/index")
    def index():
        # tag = '<input type="text" name="aaa">'
        # return render_template("index.html", tag=tag)
    
        tag = '<input type="text" name="aaa">'
        # tag = Markup(tag)
        print(tag,type(tag))
        return render_template("index.html", tag=tag,ab=ab_sum)
    
    
    if __name__ == '__main__':
        app.run()
    后端
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    
    </head>
    <body>
    
    {{ tag }}
    <br>
    {{ ab(1,2) }}
    
    </body>
    </html>
    前端
    @app.template_global()  # 定义全局模板函数
    @app.template_filter()  # 定义全局模板函数
    from flask import Flask
    from flask import render_template
    from flask import Markup  # 导入 flask 中的 Markup 模块
    
    app = Flask(__name__)
    
    
    @app.template_global()  # 定义全局模板函数
    def a_b_sum(a, b):
        return a + b
    
    
    @app.template_filter()  # 定义全局模板函数
    def a_b_c_sum(a, b, c):
        return a + b + c
    
    
    @app.route("/")
    def index():
        return render_template("index.html", tag="")
    
    
    app.run("0.0.0.0", 5000, debug=True)
    View Code
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        {{ a_b_sum(99,1) }}
        <br>
        {{ 1 | a_b_c_sum(197,2) }}
    </body>
    </html>
    View Code

     Jinja2模板复用 block

    如果我们前端页面有大量重复页面,没必要每次都写,可以使用模板复用的方式复用模板

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>Welcome OldboyEDU</h1>
        <h2>下面的内容是不一样的</h2>
        {% block content %}
    
        {% endblock %}
        <h2>上面的内容是不一样的,但是下面的内容是一样的</h2>
        <h1>OldboyEDU is Good</h1>
    </body>
    </html>
    
    index.html
    index
    {% extends "index.html" %}
    {% block content %}
        <form>
            用户名:<input type="text" name="user">
            密码:<input type="text" name="pwd">
        </form>
    {% endblock %}
    
    login.html
    login
    {% extends "index.html" %}
    {% block content %}
        <h1>欢迎</h1>
    {% endblock %}
    home
    from flask import Flask
    from flask import render_template
    
    app = Flask(__name__)
    
    
    @app.route("/login")
    def login():
        return render_template("login.html")
    
    
    @app.route("/home")
    def home():
        return render_template("home.html")
    
    
    app.run("0.0.0.0", 5000, debug=True)
    后端

    Jinja2模板语言的模块引用 include

    <form>
        用户名:<input type="text" name="user">
        密码:<input type="text" name="pwd">
    </form>
    View Code
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>Welcome OldboyEDU</h1>
        <h2>下面的内容是不一样的</h2>
        {% include "login.html" %}
        <h2>上面的内容是不一样的,但是下面的内容是一样的</h2>
        <h1>OldboyEDU is Good</h1>
    </body>
    </html>
    View Code

    Jinja2模板语言中的宏定义

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    {% macro  type_text(name,type) %}
    <input type="{{ type }}" name="{{ name }}" value="{{ name }}">
    
    {% endmacro %}
    
    <h2>在下方是使用宏来生成input标签</h2>
    
    {{ type_text("one","text") }}
    {{ type_text("two","text") }}
    
    </body>
    </html>

    5Flask 中 Session

    Flask中的Session 不是三方组件 //Flask-Session
    from flask import session

    Flask中的Session非常的奇怪,他会将你的SessionID存放在客户端的Cookie中,使用起来也非常的奇怪

     Flask 中 session 是需要 secret_key 的

    from flask import session
    app = Flask(__name__)
    app.secret_key = "aaa"

    secret_key 实际上是用来加密字符串的,如果在实例化的app中没有 secret_key 那么开启session一定会抛异常的

    session 交由客户端保管机制

    from flask import session
    
    app = Flask(__name__)
    app.secret_key = "xxx"
    
    
    @app.route("/login", methods=["GET", "POST"])
    def login():
    
        if request.method == "GET":
            return render_template("login.html")
        else:
            username = request.form.get("username")
            password = request.form.get("password")
    
            if username == "aaa" and password == "111":
                session["username"] = username
                return redirect("/student")
            else:
                return render_template("login.html",msg="用户名或者密码错误")
    @app.route("/student_list")
    def student():
        if session.get("user"):
            return render_template("student_list.html", student=STUDENT_DICT)
    
        return redirect("/login")
    View Code

    反序列化机制 -
    当客户端发起请求 - request 带上 Cookie - Cookie中有session的加密字符串 - Flask 收到Session加密字符串 - 通过secret_key解密session的加密字符串 - 获得 {username:123}

    序列化机制 - 开启session - session["username"] = uname
    先创建一个字典 {username:123} 接下来 通过secret_key + 时间戳 + 签名 加密 形成
    # eyJ1c2VybmFtZSI6IjEyMyJ9.XSVpHA.W0NfiCmW-lsTV0mvQI7mx2mf1Wo session的加密字符串

    <form action="" method="post">
        {{ msg }}
        用户名:<input type="text" name="username">
        密码:<input type="password" name="password">
    {#    <input type="file" name="myfile">#}
        <input type="submit" value="提交">
    
    </form>
  • 相关阅读:
    android音量知识总结
    android设置dialog透明度,黑暗度的方法
    获得图片资源总结
    Fragment使用案例
    activity主窗口与软键盘的交互模式
    AndroidManifest.xml中android:configChanges的简介
    2G,3G和4G网络类型了解
    安卓权限大全
    Spring
    多线程
  • 原文地址:https://www.cnblogs.com/XLHIT/p/11163554.html
Copyright © 2020-2023  润新知