• Flask入门学习教程


    Flask学习

    文章目录

    代码仓库:https://github.com/LenkyAndrews/Flask-Learning

    1.简介

    Flask是目前十分流行的web框架,采用Python编程语言来实现相关功能。它被称为微框架(microframework),“微”是指Flask旨在保持代码简洁且易于扩展,Flask框架的主要特征是核心构成比较简单,但具有很强的扩展性和兼容性。

    Flask主要包括WerkzeugJinja2两个核心函数库,它们分别负责业务处理和安全方面的功能,这些基础函数为web项目开发过程提供了丰富的基础组件。

    2.安装

    使用以下指令安装:

    pip install flask
    
    • 1

    输入指令查看版本

    import flask
    print(flask.__version__)
    # 2.0.1
    
    • 1
    • 2
    • 3

    3.最小的应用

    # 导入Flask类库
    from flask import Flask
    # 创建应用实例
    app = Flask(__name__)
    # 视图函数(路由)
    @app.route("/")
    def hello_world():
        return "Hello, World!"
    # 启动服务
    if __name__ == '__main__':
       app.run(debug = True)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    1. 首先导入了 Flask类。

    2. 接着创建一个该类的实例。第一个参数是应用模块或者包的名称。 __name__ 是一个适用于大多数情况的快捷方式。

    3. 然后使用 route()装饰器来告诉 Flask 触发函数 的 URL 。

      app.route(rule, options)
      
      • 1

      rule 参数表示与该函数的URL绑定
      options 是要转发给基础Rule对象的参数列表。

    4. 函数返回需要在浏览器中显示的信息。

    保存为app.py,一般不要使用 flask.py 作为应用名称,这会与 Flask 本身发生冲突。服务启动默认使用5000端口,在浏览器中打开 http://127.0.0.1:5000/ ,可以看到 Hello World! 字样。

    app.run(host, port, debug, options)
    
    • 1

    参数

    说明

    默认值

    host

    主机名,设置为“0.0.0.0”以使服务器在外部可用

    127.0.0.1(localhost)

    port

    端口号

    5000

    debug

    调试模式,代码更新会自动重启服务,提供一个调试器来跟踪应用程序中的错误

    False

    options

    要转发到底层的Werkzeug服务器的参数

    4.路由

    现代Web框架使用路由技术来帮助用户记住应用程序URL。Flask中的route()装饰器用于将URL绑定到函数,例如:

    @app.route('/hello')
    def hello_world():
       return 'hello world'
    
    • 1
    • 2
    • 3

    URL /hello 规则绑定到hello_world()函数,如果访问http://localhost:5000/hello,hello_world()函数的输出将在浏览器中呈现。

    5.变量规则

    通过把 URL 的一部分标记为 就可以在 URL 中添加变量,标记的部分会作为关键字参数传递给函数。

    from flask import Flask
    app = Flask(__name__)
    
    @app.route('/hello/')
    def hello(username):
        return f'Hello {username}!'
    
    if __name__ == '__main__':
       app.run(debug = True)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在上面的例子中,在浏览器中输入http://localhost:5000/hello/Kint,则Kint将作为参数提供给 hello()函数,即username的值为Kint。在浏览器中的输出如下

    Hello Kint!
    
    • 1

    通过使用 ,可以选择性的加上一个转换器,为变量指定规则。

    转换器

    说明

    string

    (缺省值) 接受任何不包含斜杠的文本

    int

    接受正整数

    float

    接受正浮点数

    path

    类似 string ,但可以包含斜杠

    完整示例:

    from flask import Flask
    from markupsafe import escape
    
    app = Flask(__name__)
    
    @app.route('/hello/')
    def hello(username):
        return f'Hello {username}!'
    
    @app.route('/post/')
    def show_post(post_id):
        return f'Post {post_id}'
    
    @app.route('/path/')
    def show_path(path):
        return f'path {escape(path)}'
    
    if __name__ == '__main__':
        app.run(debug=True)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在浏览器中输入http://localhost:5000/integer/56,输出如下

    Integer: 56
    
    • 1

    在浏览器中输入http://localhost:5000/path/templates/index.html,输出如下

    path: templates/index.html
    
    • 1

    6.URL构建

    url_for()函数用于构建指定函数的 URL。它把函数名称作为第一个参数。它可以接受任意个关键字参数,每个关键字参数对应 URL 中的变量,未知变量 将添加到 URL 中作为查询参数。

    from flask import Flask, request, redirect
    from flask import url_for
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        return 'index'
    
    @app.route('/login')
    def login():
        print(f"in login function, request.values: {request.values}")
        return 'login'
    
    @app.route('/user/')
    def profile(username):
        return f'{username}'s profile'
    
    with app.test_request_context():
        print(url_for('index'))
        print(url_for('login'))
        print(url_for('login', next='/'))
        print(url_for('profile', username='John Doe'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    url_for('login', next='/')会生成对应的URL,但next并不是login函数的关键字参数,故作为查询参数,与GET请求发送的数据类似,可以在request.values中查询到CombinedMultiDict([ImmutableMultiDict([('next', '/')])])

    输出如下:

    /
    /login
    /login?next=%2F
    /user/John%20Doe
    
    • 1
    • 2
    • 3
    • 4

    7.HTTP方法

    Web 应用使用不同的 HTTP 方法处理 URL ,HTTP方法如下(加粗的方法较为常见):

    方法

    说明

    GET

    以未加密的形式将数据发送到服务器,最常见的方法

    HEAD

    和GET方法相同,但没有响应体

    POST

    用于将HTML表单数据发送到服务器,POST方法接收的数据不由服务器缓存

    PUT

    用上传的内容替换目标资源的所有当前表示

    DELETE

    删除由URL给出的目标资源的所有当前表示

    默认情况下,Flask路由只回应 GET 请求。可以使用 route() 装饰器的 methods 参数来处理不同的 HTTP 方法。

    将以下脚本另存为welcome.html,放在templates文件夹中。

    
    
    
        
        HTTP方法
    
    
        

    Enter Name:

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    flask代码如下:

    from flask import Flask, redirect, url_for, request, render_template
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        return render_template('welcome.html')
    
    @app.route('/welcome/')
    def welcome(name):
        return f'welcome {name}'
    
    @app.route('/login', methods=['POST', 'GET'])
    def login():
        if request.method == 'POST':
            user = request.form['username']
            return redirect(url_for('welcome', name=user))
        else:
            user = request.args.get('username')  # GET方法获取数据,args是包含表单参数对及其对应值对的列表的字典对象。
            return redirect(url_for('welcome', name=user))
    
    if __name__ == '__main__':
        app.run(debug=True)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    如果请求方式是POST方法,则通过以下代码获得从表单数据获得的“username”参数的值:

    user = request.form['username']
    
    • 1

    如果请求方式是GET方法,则通过以下代码获得从表单数据获得的“username”参数的值:

    user = request.args.get('username')
    
    • 1

    args是包含表单参数对及其对应值对的列表的字典对象,与’username’参数对应的值将传递到/welcome URL中,即

    /login?username=Kint
    
    • 1

    8.文件存放

    flask项目中,static文件夹中存放CSS 和 JavaScript文件,templates文件夹中存放html文件。app.py与templates和static文件夹同级目录。

    /app.py
    /templates
        /index.html
    /static
        /style.css
        /jquery.js
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    果然想要更改路径可以在初始化Flask实例时进行修改

    app = Flask(__name__, static_folder='', template_folder='')
    
    • 1

    9.渲染模板

    使用 render_template() 方法可以渲染模板,提供模板名称和需要作为参数传递给模板的变量。

    在templates文件夹下创建render_template.html文件,代码如下:

    
    
    
        
        render_template
    
    
        

    渲染模板

    {{ my_int }}
    {{ my_str }}
    {{ my_list }}
    {{ my_dict }}

    列表数据获取

    {{ my_list[0] }}
    {{ my_list.1 }}

    字典数据获取

    {{ my_dict['name'] }}
    {{ my_dict.age }}

    算术运算

    {{ my_list.0 + 10 }}
    {{ my_list[0] + my_list.1 }}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    flask代码如下:

    from flask import Flask, render_template
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        int_ = 1024
        str_ = 'Hello World!'
        list_ = [1, 2, 3, 4, 5]
        dict_ = {'name': 'Kint', 'age': 23}
        # render_template方法:渲染模板
        # 参数1: 模板名称  参数n: 传到模板里的数据
        return render_template('render_template.html', my_int=int_, my_str=str_, my_list=list_, my_dict=dict_)
    
    if __name__ == '__main__':
        app.run(debug=True)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    效果如下:

    在这里插入图片描述

    Flask 是使用 Jinja2 这个模板引擎来渲染模板,更多内容,详见官方 Jinja2 模板文档

    10.Request对象

    部分属性如下(加粗的较为常见):

    属性

    说明

    method

    请求方法,比如GET、POST

    data

    以字符串的形式存储请求的数据

    files

    上传的文件,类型为MultiDict

    args

    解析URL中提交的参数,类型为MultiDict

    form

    上传的表单数据,类型为MultiDict

    values

    包含args和form的数据,类型为CombineMultiDict

    json

    解析JSON数据,如果没有则返回None

    cookies

    包含客户端传输的所有 cookies ,类型为MultiDict

    headers

    请求头信息,类似字典,可通过关键词获取对应得信息

    在templates文件夹下创建Request.html文件,代码如下:

    
    
    
        
        Request
    
    
        

    账号:

    密码:

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    flask代码如下:

    from flask import Flask, request, render_template
    import json
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        return render_template("Request.html")
    
    @app.route('/login', methods=["GET", "POST"])
    def login():
        print('request.method:
    ', request.method)
        print('request.data:
    ', request.data)
        print('request.request.args:
    ', request.args)
        print("request.request.args.get('b'):
    ", request.args.get('c'))
        print('request.form:
    ', request.form)
        print("request.request.form.get('password'):
    ", request.form.get('password'))
        print('request.values:
    ', request.values)
        print('request.json:
    ', request.json)
        print('request.cookies:
    ', request.cookies)
        print('request.headers:
    ', request.headers)
        return json.dumps(request.form) # 将MultiDict数据处理为JSON数据
    
    if __name__ == '__main__':
        app.run(debug=True)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    效果如下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ouaD3STh-1659334474331)(https://media.giphy.com/media/1fuRoc92CZJU93oGOu/giphy.gif)]

    后端输出如下:

    在这里插入图片描述

    在这里插入图片描述

    以request.form为例,在获取MultiDict的值时,推荐使用request.form.get(key)而不直接使用request.form[key],前一种方式可以避免关键词缺失而导致的KeyError。

    获取各种路径,本例中的URL为http://127.0.0.1:5000/login?a=1&b=2

    print('url: ', request.url)
    print('base_url: ', request.base_url)
    print('host: ', request.host)
    print('host_url: ', request.host_url)
    print('path: ', request.path)
    print('full_path: ', request.full_path)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    输出为:

    url:  http://127.0.0.1:5000/login?a=1&b=2
    base_url:  http://127.0.0.1:5000/login
    host:  127.0.0.1:5000
    host_url:  http://127.0.0.1:5000/
    path:  /login
    full_path:  /login?a=1&b=2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    11.Cookie

    Cookie以文本文件的形式存储在客户端的计算机上。其目的是记住和跟踪与客户使用相关的数据,以获得更好的访问者体验和网站统计信息。比如网站为了辨别用户身份、进行会话跟踪需要把一些数据 (例如:登录状态、用户名称) 储存在用户本地终端上,这些数据被称为 Cookie。

    Request对象包含Cookie的属性,它是所有Cookie变量及其对应值的字典对象。

    在Flask中,对Cookie的处理步骤为:

    1. 使用Response对象的set_cookie()方法设置cookie
    2. 通过request.cookies的方式获取cookies,返回的是一个字典
    3. 使用Response对象的delete_cookie()方法设置cookie

    在templates文件夹下创建get_cookie.html文件,代码如下:

    
    
    
        
        获取cookie
    
    
        

    在服务端获取cookie: {{cookie}}

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在templates文件夹下创建show_cookie_by_JQuery.html文件,代码如下:

    
    
    
        
        设置cookie
        
    
    
        

    在服务端设置cookie

    在客户端通过JQuery读取cookie:

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    flask代码如下:

    from flask import Flask, request, Response, render_template, make_response, redirect, url_for
    
    app = Flask(__name__)
    
    
    @app.route('/')
    def index():
        return redirect(url_for('set_cookie'))  # 重定向响应的URL
    
    # 获取cookie
    @app.route('/get_cookie')
    def get_cookie():
        cookie = request.cookies.get('user') # 获取关键字为user对应cookie的值
        print(cookie)
        return render_template('get_cookie.html', cookie=cookie)
    
    
    # 设置cookie
    @app.route('/set_cookie')
    def set_cookie():
        html = render_template('show_cookie_by_JQuery.html')
        response = make_response(html)  # 设置响应体
        # response = Response(html)
        response.set_cookie('user', 'Kint')
        return response
    
    
    # 删除cookie
    @app.route('/del_cookie')
    def del_cookie():
        html = render_template('show_cookie_by_JQuery.html')
        response = Response(html)
        response.delete_cookie('user')
        return response
    
    
    if __name__ == '__main__':
        app.run(debug=True)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    在set_cookie()函数中,首先渲染模板文件show_cookie_by_JQuery.html,通过make_response()方法设置响应体并返回Response对象,然后设置cookie。以下两种写法作用相同:

    response = make_response(html)  # 设置响应体
    response = Response(html)
    
    • 1
    • 2

    在浏览器中输入http://127.0.0.1:5000/set_cookie,可以看到在响应头信息中已经设置好cookie的数据了。

    在这里插入图片描述

    在浏览器中输入http://127.0.0.1:5000/get_cookie,可以看到请求头信息中cookie的数据,并且将cookie传输到服务端上。

    在这里插入图片描述

    在浏览器中输入http://127.0.0.1:5000/del_cookie,此时响应体信息中已经没有user对应的cookie值了。

    在这里插入图片描述

    12.会话Session

    与Cookie不同,Session数据存储在服务器上,用来存储用户的信息 (例如登录状态、用户名称)。Session 有一个唯一标识 ID,对应一个用户,在服务端使用 ID 可以查找到对应用户的数据,故Flask应用程序需要一个定义的密钥SECRET_KEY

    以下代码简单实现判断用户是否登录功能:

    from flask import Flask, redirect, url_for, request, session
    
    app = Flask(__name__)
    app.secret_key = 'abc'
    
    @app.route('/')
    def index():
        if 'user' in session:
            # 获取会话中的用户信息
            user = session.get('user')
            return '登录用户是:' + user + '
    ' + "点击这里注销" return "

    暂未登录


    " + "点击这里登录" @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': # 设置会话中的用户信息 session['user'] = request.form['user'] return redirect(url_for('index')) return '''

    ''' @app.route('/logout') def logout(): # 删除会话中的用户信息 session.pop('user') return redirect(url_for('index')) if __name__ == '__main__': app.run(debug=True)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    效果如下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-riajoEgf-1659334474332)(https://media.giphy.com/media/BCziOildYKLzNY4DCl/giphy.gif)]

    实例1.上传表单数据

    文件结构如下:

    /app.py
    /templates
        /login.html
        /result.html
    
    • 1
    • 2
    • 3
    • 4

    app.py代码如下:

    from flask import Flask, render_template, request
    app = Flask(__name__)
    @app.route('/')
    def student():
       return render_template('login.html')
    
    
    @app.route('/result',methods = ['POST', 'GET'])
    def result():
       if request.method == 'POST':
          result = request.form #拿到前端传输的表单数据
          return render_template("result.html",result = result)
    
    
    if __name__ == '__main__':
       app.run(debug = True)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在templates文件夹下创建login.html文件,代码如下:

    
    
    
        
        实例1.上传表单数据—登录页面
    
    
        

    Name

    Email

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在templates文件夹下创建result.html文件,代码如下:

    
    
    
        
        实例1.上传表单数据-结果页面
    
    
        
            {% for key, value in result.items() %}
            
            {% endfor %}
        
    {{ key }} {{ value }}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    实例2.上传下载文件

    文件结构如下:

    /app.py
    /templates
        /index.html
        /upload.html
    /upload
        /download_sample.txt
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    app.py代码如下:

    from flask import Flask, render_template, request, send_from_directory
    from werkzeug.utils import secure_filename
    
    import os
    
    app = Flask(__name__)
    app.config['UPLOAD_FOLDER'] = 'upload/'
    app.config['MAX_CONTENT_LENGTH'] = 16 * 1000 * 1000  # 上传文件大小限制为16M,如果超过会抛出异常
    
    @app.route('/')
    def upload_file():
        return render_template('index.html')
    
    @app.route('/upload', methods=['GET', 'POST'])
    def upload():
        if request.method == 'POST':
            f = request.files['file']
            print(request.files)
            # secure_filename检查客户端上传的文件名,确保安全,注意文件名称不要全中文!!!
            f.save(os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(f.filename)))
            return render_template('upload.html')
        else:
            return render_template('index.html')
    
    @app.route('/download/', methods=['GET', 'POST'])
    def download(filename):
        # as_attachment=True 表示文件作为附件下载
        return send_from_directory('./upload', filename, as_attachment=True)
    
    if __name__ == '__main__':
        app.run(debug=True)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    upload函数中,f.save的作用是将文件保存到指定路径中。在使用secure_filename检验上传文件名称时,注意名称尽量为英文!

    download函数中,send_from_directory方法将upload目录下的指定文件发送到客户端,as_attachment=True表示文件作为附件下载。

    在templates文件夹下创建index.html文件,代码如下:

    
    
    
        
        实例2.上传下载文件
    
    
        

    上传文件

    下载文件

    download_sample.txt
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在templates文件夹下创建upload.html文件,代码如下:

    
    
    
        
        实例2.文件上传成功页面
    
    
        

    文件上传成功!

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    c-数组的初始化和定义-day9
    React Native 环境搭建
    一、Unity环境安装
    个人博客搭建记录(不用CSDN了)
    ZTE ZXR10 5250 command hints
    LVGL库入门教程02-基本控件与交互
    Golang基本命令操作
    SPA项目开发之CRUD+表单验证
    靶场通关记录
    tsconfig.json在配置文件中找不到任何输入,怎么办?
  • 原文地址:https://blog.csdn.net/m0_67392661/article/details/126100294