• Flask小项目教程(含MySQL与前端部分)


    1. 环境配置

    首先我们在项目的根目录下创建一个 Python 虚拟环境,打开命令行输入以下指令:

    python -m venv venv
    
    • 1

    启动虚拟环境:

    .\venv\Scripts\Activate.ps1
    
    • 1

    如果遇到报错:.\venv\Scripts\Activate.ps1 : File ...\venv\Scripts\Activate.ps1 cannot be loaded because running scripts is disabled on this system.,说明可能是系统禁止运行脚本,打开 PowerShell 查看一下系统当前的执行策略:

    get-executionpolicy
    
    • 1

    如果为 Restricted 说明此系统不载入任何配置文件,不运行任何脚本。我们需要修改一下执行策略,以管理员身份打开 PowerShell,使用以下指令修改执行策略:

    Set-ExecutionPolicy Unrestricted  # 设置全局的执行策略
    Set-ExecutionPolicy -Scope CurrentUser Unrestricted  # 设置当前用户的执行策略
    
    • 1
    • 2

    接下来我们安装 Flask:

    pip install flask
    
    • 1

    2. 快速搭建Flask应用程序

    我们先看一下如何创建 URL 与函数的对应关系:

    from flask import Flask
    
    app = Flask(__name__)  # 实例化Flask类的对象
    
    @app.route("/index")
    def index():
        return "

    Hello World!

    "
    if __name__ == "__main__": app.run()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    其中的 @app.route 作用是创建了网址 /indexindex 函数的对应关系。现在我们运行程序,能看到终端的输出: * Running on http://127.0.0.1:5000,然后我们访问 http://127.0.0.1:5000/index 即可看到 Hello World!

    app.run() 方法中有以下几个参数:

    • host:主机名,默认为 127.0.0.1(即 localhost)。
    • port:端口号,默认为5000。
    • debug:是否开启 DEBUG 模式,默认为 False,开启后每次对代码进行修改保存后直接刷新网页即可实时显示效果,否则需要手动重启项目才能看到改动。

    注意我们返回的字符串中有

    标签,这是 HTML 标签,整个项目的逻辑是用户(浏览器)访问 URL 时向 Web 应用(此处就是 Flask)发送请求,然后 Web 应用向浏览器返回一个字符串,浏览器是具备解析

    这类 HTML 标签的能力的。前端部分的学习可以在 Web 专栏中找到。

    Tips:PyCharm 输入 main 即可自动补全出 if __name__ == "__main__":,VS Code 则需要进行配置,点击左下角的齿轮,选择 User Snippets(用户代码片段),然后在弹出的下拉选框中选择 python,这时会出来一个配置文件 python.json,然后向该文件中添加 "Print to console" 项,修改后如下:

    {
    	"Print to console": {
    		"prefix": "main",
    		"body": [
    			"if __name__ == '__main__':",
    			"    ${1:pass}",
    			"",
    		],
    		"description": "python--main"
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    Flask 框架为了让我们写 HTML 标签更方便,支持将这些内容写到一个单独的文件中,render_template 函数可以渲染 HTML 文件,默认是从项目根目录下的 templates 目录中开始寻找文件,我们创建 templates 目录并创建一个 index.html 如下:

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Indextitle>
    head>
    <body>
        <h1>Hello World!h1>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    现在就可以将之前的字符串改为渲染一个 HTML 文件了:

    from flask import Flask, render_template
    
    app = Flask(__name__)  # 实例化Flask类的对象
    
    @app.route("/index")
    def index():
        return render_template("index.html")
    
    if __name__ == "__main__":
        app.run()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    假设我们在页面中需要引入一张本地的图片,在 Flask 中要求我们需要将图片这类静态文件(还有视频、音频、CSS、JS 等)放在项目根目录中的 static 目录下,假设我们有一张图片放在 static/image 目录下,那么就可以直接用相对路径调用该图片了:

    DOCTYPE html>
    <html lang="en">
    ...
    <body>
        <h1>Hello World!h1>
        <img src="/static/image/background.jpg" />
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3. Flask接收HTTP请求

    假设我们需要实现一个注册页面,那么浏览器就需要将用户输入的信息发送到后端服务器,发送请求的方式有 GET 和 POST,这两种方式的主要区别如下:

    • GET 请求是通过 URL 传递参数,而 POST 请求是通过请求体传递参数。这意味着 GET 请求的参数在浏览器地址栏中可见,而 POST 请求的参数则不可见。
    • GET 请求的参数长度受到 URL 长度的限制,不同的浏览器和服务器有不同的限制,一般在2KB到8KB之间。POST 请求的参数长度没有明确的限制,主要取决于 HTTP 协议和服务器配置。
    • GET 请求是幂等的,即多次发送相同的 GET 请求,服务器返回的结果也相同。POST 请求不是幂等的,因为每次发送 POST 请求可能会修改服务器上的资源状态。
    • GET 请求可以被浏览器缓存,也可以被收藏为书签。POST 请求不会被缓存,也不能被收藏为书签。
    • GET 请求一般用于获取数据,比如搜索、查询、排序等操作。POST 请求一般用于提交数据,比如表单、登录、注册等操作。
    • GET 请求只能发送 ASCII 字符,而 POST 请求可以发送多种类型的数据,比如表单、文件、二进制等。

    @app.route 有一个参数叫做 methods,表示前端访问该 URL 时发送请求的方式,例如 methods=['GET'] 表示浏览器只能用 GET 请求方式访问该 URL。

    我们假设现在有一个用于注册的前端页面 register.html,其中有两个表单分别为 GET 请求和 POST 请求:

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Registertitle>
    head>
    <body>
        <h1>Registerh1>
        <hr>
        <form method="get" action="/register/get">
            <fieldset>
                <legend>GET Formlegend>
                <label for="get_username">账号:label>
                <input type="text" name="username" id="get_username" placeholder="Please input username">
                <br>
            
                <label for="get_password">密码:label>
                <input type="password" name="password" id="get_password" placeholder="Please input password">
                <br>
    
                <button type="subimt" id="get_submit">GET Submitbutton>
            fieldset>
        form>
        <hr>
        <form method="post" action="/register/post">
            <fieldset>
                <legend>POST Formlegend>
                <label for="post_username">账号:label>
                <input type="text" name="username" id="post_username" placeholder="Please input username">
                <br>
            
                <label for="post_password">密码:label>
                <input type="password" name="password" id="post_password" placeholder="Please input password">
                <br>
    
                <button type="subimt" id="post_submit">POST Submitbutton>
            fieldset>
        form>
    body>
    html>
    
    • 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
    • 39
    • 40
    • 41

    我们在 Flask 后端可以通过 request 接收前端提交过来的表单的内容:

    from flask import Flask, render_template, request
    
    app = Flask(__name__)  # 实例化Flask类的对象
    
    @app.route("/register")
    def register():
        return render_template("register.html")
    
    @app.route("/register/get", methods=["GET"])
    def register_get():
        print(request.args)  # GET请求的内容在args中
        print(request.args.get("username"))  # 获取username,如果有多个数据用getlist
        return "GET Register"
    
    @app.route("/register/post", methods=["POST"])
    def register_post():
        print(request.form)  # POST请求的内容在form中
        print(request.form.get("username"))
        return "POST Register"
    
    if __name__ == "__main__":
        app.run()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    通过 GET 方式提交的表单 URL 为:http://127.0.0.1:5000/register/get?username=AsanoSaki&password=123456,而通过 POST 方式提交的表单 URL 为:http://127.0.0.1:5000/register/post

    后端的输出内容如下:

    ImmutableMultiDict([('username', 'AsanoSaki'), ('password', '123456')])  # GET
    ImmutableMultiDict([('username', 'AsanoSaki'), ('password', '123456')])  # POST
    
    • 1
    • 2

    由于我们的 /request/post 地址只支持 POST 请求,因此如果直接输入地址访问的话将会提示 The method is not allowed for the requested URL.。现在我们假设注册只用 POST 请求,那么我们就可以将 /request/post 的内容合并到 /request 中,然后判断前端发来的请求如果为 GET 就渲染 register.html,如果为 POST 就接收表单信息:

    from flask import Flask, render_template, request
    
    app = Flask(__name__)  # 实例化Flask类的对象
    
    @app.route("/register", methods=["GET", "POST"])
    def register():
        if request.method == "GET":
            return render_template("register.html")
        elif request.method == "POST":
            print(request.form)  # POST请求的内容在form中
            print(request.form.get("username"))
            return "POST Register"
    
    if __name__ == "__main__":
        app.run()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    对应的 register.html 如下:

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Registertitle>
    head>
    <body>
        <h1>Registerh1>
        <hr>
        <form method="post" action="/register">
            <fieldset>
                <legend>POST Formlegend>
                <label for="post_username">账号:label>
                <input type="text" name="username" id="post_username" placeholder="Please input username">
                <br>
            
                <label for="post_password">密码:label>
                <input type="password" name="password" id="post_password" placeholder="Please input password">
                <br>
    
                <button type="subimt" id="post_submit">POST Submitbutton>
            fieldset>
        form>
    body>
    html>
    
    • 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
  • 相关阅读:
    2150. 找出数组中的所有孤独数字-快速排序
    IPv6与IPv4的区别 网信办等三部推进IPv6规模部署
    大学生餐饮主题网页制作 美食网页设计模板 学生静态网页作业成品 dreamweaver美食甜品蛋糕HTML网站制作
    Day981.OAuth 2.0的工作流程与安全问题 -OAuth 2.0
    三大云厂商 ARM 架构服务器性能对比
    YUV图像格式
    vue3 - 使用reactive定义响应式数据进行赋值时,视图没有改变,值已经改变的解决方案
    【Python数据科学快速入门系列 | 02】创建ndarray对象的十多种方法
    lua-arm平台交叉编译
    高内聚、低耦合、高并发、高可用、分布式这些名称到底什么意思?
  • 原文地址:https://blog.csdn.net/m0_51755720/article/details/133612799