• 【无标题】


    flask工具书-搭建一个简单Web应用

    作者:林水火

    说明:文档配图懒得添加了, 可以看我的csdn上传的同名资源

    网络框架是一种工具,用于快速和容易地开发Web应用程序。它提供了许多常见的功能,例如用户认证、管理面板、表单处理和文件上传等,避免了重复编写代码的麻烦。

    Flask是一个轻量级的、简单易用的Python Web网络应用程序框架。

    当用户向服务器请求一个网站时,服务器会将请求传递给Flask。Flask通过URL确定请求的具体内容,然后调用相应的视图函数进行处理。视图函数可以执行各种操作,例如查询数据库、修改数据等,最终生成响应并发送给用户的Web浏览器。

    1.第一个WEB服务

    在flask运行后,请不要关闭代码终端。以下是基础代码解释:

    **app:**我们可以称呼变量app为一个“实例”或“对象”,它有专属的“方法”与“属性”,我们后续所做的一切都是对app这个对象进行修改。

    **route:**该单词的中文含义为:路由,它的主要作用是将URL路径和函数关联起来,route方法的参数即URL网址的内容,每个路由后面一般都会跟一个函数。例如,当前路由中的(‘/’)代表根目录,用户在输入IP地址和端口号后,index函数的返回值就是访问服务器所见内容。

    **if name == ‘main’😗*python文件通常有两种使用方法

    ①直接执行当前文件

    ②import到其他的 python 文件中,作为第三方库被调用

    加入该语句后,直接运行该程序才可以启动web服务器,如果他人import当前文件,则服务器不会启动,但是其中的视图函数等内容可以被引用。

    from flask import Flask 	#引入Flask包
    
    app = Flask(__name__) 		#创建一个Web应用的实例app
    
    @app.route('/') 			#设定路由
    def index(): 				#当浏览器中的地址符合路由规则时,就会进入该函数
    	return 'Hello World'
    if __name__ == '__main__': 	#启动Web服务器
    	app.run()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    [外链图片转存中…(img-eUyvoTcs-1695969725031)]

    可以在浏览器中打开"http://127.0.0.1:5000/"访问该程序生成的web页面。

    Q:访问网页时,在URL的末尾,是否需要加斜杠呢?
    A:在某些浏览器中,当URL末尾没有斜杠时,浏览器可能会补全斜杠再发送请求。例如,在浏览器中输入baidu.com,就会自动来到https://www.baidu.com/。因此,实际的URL末尾是需要斜杠的。
    
    • 1
    • 2

    2.路由传递信息

    2.1获取信息

    同样是使用路由函数,将其路径从"/“改为”/hello/",就需要在URL的最后加上对应内容,<>这类括号是路由方法中特有的,我们后续会使用其他方法

    from flask import Flask
    app = Flask(__name__)
    @app.route('/hello/')
    def hello(name):
        return 'Hello ' + name
    
    @app.route('/user/')
    def get_user(user_id):
        return 'User ID: ' + str(user_id)
    
    @app.route('/content///')
    def login(username, password):
        return '用户名:' + username + '密码:' + password
    
    if __name__ == '__main__': 
        app.run()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    现在我们向浏览器的地址栏中输入http://localhost:5000/hello/lin,你将在页面上看到”Hello lin”的字样。URL路径中/hello/后面的参数被作为hello()函数的name参数传了进来。

    [外链图片转存中…(img-ir537G5x-1695969725032)]

    2.2简单应用

    from flask import Flask# 从flask框架中导入Flask类
    app = Flask(__name__)# 传入__name__初始化一个Flask实例
    app.config['JSON_AS_ASCII']=False
    books = ['三国演义', '水浒传', '西游记', '红楼梦']
    @app.route('/book/')
    def book_detail(book_id):
        if book_id < len(books):
            return books[book_id]
        else:
            return "没有找到"
    if __name__ == '__main__':
        app.run()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    这里我们调用传入的数据进行判断,注意路由的变化。

    [外链图片转存中…(img-8V9XmNfZ-1695969725032)]

    3.GET/POST传递信息

    在@app.route()中可以传入一个关键字参数methods,来指定该路由支持的HTTP方法,可填写HTTP协议**中的两种常见请求方法:GET和POST,其他方法不做要求。

    方法名作用使用说明程序实现
    GET从服务器获得数据将数据按照variable=value的形式,添加到URL后面,并使用“?”连接,变量之间使用“&”连接;例如baidu.com/s?wd=百度request.args.get(‘name’)
    POST向服务器传递数据将表单中的数据放在form的数据体中,按照变量和值相对应的方式,传递到action所指向URL。request.form.get(‘name’)

    3.1GET

    使用该程序,能像代码2.1一样从URL中获取数据,请你思考:这两种方式有何区别?

    from flask import Flask,request
    app = Flask(__name__)
    
    @app.route('/',methods=['GET'])
    def hello():
        name=request.args.get("name") # 字符串name代表获取输入时的url中的该变量内容
        return "Hello "+name
    
    @app.route('/user',methods=['GET'])
    def user():
        name=request.args.get('name')
        psd=request.args.get('psd')
        return "用户名:" + name +"密码:" + psd
    
    if __name__ == '__main__':
        app.run()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    [外链图片转存中…(img-oAcvSsI9-1695969725032)]

    3.2POST

    POST方法需要配合页面使用,这里我们使用了render_template函数,让初始页面指向一个html文件’index.html’,该文件已被存放于templates文件夹下,请勿重命名文件夹或HTML文件。

    from flask import Flask,request,render_template
    
    app = Flask(__name__)
    
    @app.route('/')
    def hello():
        return render_template('index.html')
    
    @app.route('/login',methods=['POST'])
    def login():
        name=request.form.get("name")
        return "欢迎登录:" + name
    
    if __name__ == '__main__':
        app.run()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    index.html中的内容

    <form action="/login" method="post">
        <p>用户名p>
        <p><input type="text" name="user" />p>
        <p><input type="submit" value="确定"/>p>
    form>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    [外链图片转存中…(img-SdsGlvqx-1695969725033)]

    使用post方法后,我们的url中不会显示任何用户输入的信息。

    4.总结

    数据传输方法定义方法特点备注
    路由传递信息[外链图片转存中…(img-Pp1ljEBc-1695969725033)]在使用时访问对应路由浏览即可
    HTTP方法传递信息[外链图片转存中…(img-gtZKHcdB-1695969725033)]GET方法会将数据存储于URL中传递
    POST方法的常见特征是:网页中有可提交的表单
    需了解用户在访问不同路由时,服务器返回的内容

    5.其他知识

    5.1 Html基础语法

    **HTML是什么?**一种可以被浏览器渲染的文本。

    **HTML有什么用?**它是我们平时看到网页的实际内容,文本经渲染后才成为了我们看到的表单、图片、页面特效等等。

    **需要掌握多少?**简单浏览即可,不用会写,考试也不考HTML语法。

    如想了解更多,可以访问教程

    html在线编辑器

    5.1.1HTML 标签

    • HTML 标签是由尖括号包围的关键词,比如
    • HTML 标签通常是成对出现的,比如

    • 标签对中的第一个标签是开始标签,第二个标签是结束标签

    5.1.2HTML结构

    [外链图片转存中…(img-LgbaYRil-1695969725033)]

    5.1.3 常用语法

    超链接:href是hypertext reference的缩写,代表超文本引用。

    任意文本
    
    • 1

    在上面的代码中,’任意文本’是一段普通文本,'href’是该标签中的属性。

    加载图像:图像标签包括和源属性Src,源属性(src)指 “source”。源属性的值是图像的 URL 地址。

    定义图像的语法是:

    
    
    • 1

    URL 指存储图像的位置。如果名为 “pulpit.jpg” 的图像位于 www.runoob.com 的 images 目录中,那么其 URL 为 http://www.runoob.com/images/pulpit.jpg。也可以使用本地的路径。

    换行:br是break的缩写


    • 1

    5.2 了解SQL

    **为什么是“了解”?**第四章我们会进一步学习数据库,这里仅作简单了解。

    **数据库是什么?**按照数据结构来组织、存储和管理数据的仓库。

    SQL是什么? SQL是Structured Query Language(结构化查询语言)的缩写,是用于访问和处理数据库的标准的计算机语言,你会看到许多用于处理数据库的python库或数据库软件都叫sqlxxx xxxsql,就像python的编辑器叫pycharm、thonny一样。

    **教材用的操作数据库的python库是什么?**sqlite3

    [外链图片转存中…(img-kcgC378c-1695969725033)]

    需要注意的是,“create table、insert into”都是sql语言,而不是python语言,因此我们需要使用特定的函数来执行这些sql语言。

    什么是游标对象?

    使用sqlite3库时,要想实现数据库操作,必须创建数据库对象如db,再针对该数据库对象创建游标对象cur,在数据库内进行读取。

    可以将游标理解为一个柜子,每次只能选中一排柜子里的东西,那么就需要不断移动我们的指针,找到我们想要的的东西。

    [外链图片转存中…(img-FUttk3y1-1695969725034)]

    常见代码有哪些?

    在python中操作数据库需要用到cur.execute语句,其作用就是将字符串看作SQL语句,并执行,其中的cur是我们定义的游标/指针对象

    cur.execute("INSERT INTO tp(地址,学号) VALUES('%s','%s')" %(ip,'0'))
    
    • 1

    例如上方的代码,就是向数据表tp的地址和学号列插入(insetr)了数据

    一些重要的 SQL 命令

    SELECT - 从数据库中提取数据

    UPDATE - 更新数据库中的数据

    DELETE - 从数据库中删除数据

    INSERT INTO - 向数据库中插入新数据

    CREATE DATABASE - 创建新数据库

    CREATE TABLE - 创建新表

    DROP TABLE - 删除表

    6.拓展1_Jinja2模板

    [外链图片转存中…(img-LTpPIwqB-1695969725034)]

    网页模板是什么?:在案例3.2中,我们已经调用过了render_template函数读取特定目录下的html文件,这就是模板的调用。我们在渲染一个网页的时候,并不是只渲染一个纯文本字符串,而是需要渲染一个内容复杂的html文档。

    html文件能自动生成吗?:例如,根据本次读取的学生名单,用代码循环生成班级人数个的投票选择框。为了解决这一任务,我们就提出了这样的需求:根据flask中的代码,自动调整html页面中的内容。

    **如何实现?:**Jinja2是一个模板引擎,它是Flask框架的默认模板引擎,了解其语法规范,分别在python代码和html代码中进行对应修改,就可以满足我们刚才提出的需求。

    **这个名字是什么意思?:**template模板 /ˈtempleɪt/ temple 寺庙 /ˈtempl/
    其命名与日本的神社有些相似之处,这么看来,这个库的名字还曾有机会成为Miao的。

    6.1基础模板

    from flask import Flask #引入Flask包
    app = Flask(__name__) #创建一个Web应用的实例app
    @app.route('/') #指明地址是根路径
    def index(): #当请求的地址符合路由规则时,就会进入该函数。
    	return render_template('index.html')
    if __name__ == '__main__': #启动Web服务器
    	app.run()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在该代码目录下,创建一个子目录”templates”(注意,一定要使用这个名字)。然后在”templates”目录 下创建文件”index.html”。

     <h1>欢迎您h1>
    
    • 1

    以上代码调用了另一个文件。

    6.2Jinja2模板调用

    在上述除3.2的代码中,flask完成了两个任务:①处理数据②展示信息,flask能够将这两个任务分离,在路由函数中专注于处理具体任务,而信息的展示则交由Jinja2模板引擎完成。在该模板中,有一些特殊的语法**(浏览即可,无需记住)**。

    {{ … }}:用来装载一个变量,模板渲染的时候,会把这个变量代表的值替换掉。并且可以间接访问一个变量的属性或者一个字典的key。访问字典对象的值时,就行DataFrame对象一样,点号访问和[]中括号

    {% … %}:所有的控制语句都是放在{% … %}中,并且有一个语句{% endxxx %}来进行结束,Jinja中常用的控制语句有if/for…in.

    {# … #}:用来装载一个注释,模板渲染的时候会忽视这中间的值。

    例如,下方代码对比4.1,仅在render_template函数中添加了变量,就能完成信息的传递(user为html中提前定义好的变量名)。

    from flask import Flask,render_template
    app = Flask(__name__)
    @app.route('/')
    def index():
        return render_template('index.html',name = 'lin')
    if __name__ == '__main__':
        app.run()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    html内容

    <h1>欢迎您{{name}}h1>
    
    • 1

    运行结果:

    [外链图片转存中…(img-AP5E0IAq-1695969725034)]

    7.拓展2_表单

    HTML中的form表单提供了交互控制元件,用于收集用户输入的内容,向Web服务器提交信息。

    格式(缩进不影响效果):

    <form>
    	<p>表单中的内容,如果没有input属性那就只是一段普通文本p>
    form>>
    
    • 1
    • 2
    • 3

    关键属性:

    action:提交表单时执行的动作,通常表单会被提交到web服务器上的某个网页。

    method:提交表单时所用的HTTP方法(GET或者POST)

    [外链图片转存中…(img-V9drVwdi-1695969725034)]

    其中的input类型有多种可选类型,如Text文本、Check复选框、Radio单选按钮、Select 下拉列表、File选取文件、Submit and Reset Button提交或者重置按钮控件。上方html代码经浏览器渲染后如下所示

    姓名:

    性别:男 女

    7.1Flask处理通用表单(在html中书写静态表单)

    web服务器代码:当请求路径为http://127.0.0.1:5000/时,render_template()函数呈现templates文件夹内index.html的内容,按下提交按钮时即提交表单数据,执行action动作,表单数据提交到http://127.0.0.1:5000/success,根据不同http方法,执行不同分支,页面呈现不同内容。

    from flask import Flask,render_template,request
    app = Flask(__name__)
    @app.route('/')
    def index():
        return render_template("index.html")
    @app.route('/success', methods=['GET', 'POST'])
    def login():
        if request.method == 'GET':
            return "响应 GET 请求,提交表单数据成功!"
        else:
            return "响应 POST 请求,提交表单数据成功!"
        
    if __name__ == "__main__":
        app.run(debug=True)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    index.html内容:

    GET方法提交表单数据

    姓名:

    性别:

    POST方法提交表单数据

    姓名:

    性别:

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

    GET方法提交表单效果:

    [外链图片转存中…(img-ZktxWOSS-1695969725035)]

    POST方法提交表单数据效果:

    [外链图片转存中…(img-v7Ih1XYT-1695969725035)]

    何时使用GET?何时使用POST?

    如果表单提交是被动的(比如搜索引擎查询),提交数据量较少且没有敏感信息,可以选择使用 GET ,注意:有表单也可以使用get方式提交,此时表单数据在页面地址栏中是可见的。

    如果表单数据需要更新,或者包含敏感信息(例如密码),POST 的安全性更好,在页面地址栏中被提交的数据是不可见的。

    7.2Flask_wtf的使用(html接收来自代码的动态表单)

    WTForms是一个灵活的表单,渲染和验证库。 使用Flask-WTF,可以在Python脚本中定义表单域并使用HTML模板来呈现它们, 也可以将验证应用于WTF字段。

    为什么使用flask_wtf?

    • 方便动态呈现表单元素。
    • HTML本身无法验证用户的输入,使用该拓展可以对输入内容进行验证。

    首先,需要安装flask_wtf拓展。

    pip install flask_wtf
    
    • 1

    flask_wtf内置标准表单字段

    字段描述
    StringField单行文本输入框
    TextField单行文本输入框
    BooleanField多选框
    RadioField单选框
    SelectField下拉列表框
    TextAreaField多行长文本输入框
    PasswordField密码输入框(输入内容自动变为*)
    SubmitField提交按钮

    例如,我们想要实现一个登录的网页表单,包含一个文本输入框,一个密码输入框和一个提交按钮。

    Python定义一个表单类:

    from flask_wtf import FlaskForm                                #导入表单模块
    from wtforms import StringField,PasswordField,SubmitField      #导入表单相关模块
    Class LoginForm(FlaskForm):     #设置网页表单类
        name=StringField("用户名:")       #字符输入框
        password=PasswordField("密码:")  #密码输入框
        submit=SubmitField("登录")        #提交按钮
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    表单类实例化

    form = LoginForm()
    
    • 1

    渲染时,等效html脚本如下:

    <form>
         <p>用户名:<input type="text" name="name">p>
         <p>密码:<input type="password" name="password">p>
         <p><input type="submit" value="登录">p>
    form>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    web服务器完整代码:

    from flask import Flask,render_template,request                #导入flask模块
    from flask_wtf import FlaskForm                                #导入表单模块
    from wtforms import StringField,PasswordField,SubmitField      #导入表单相关模块
    
    app=Flask(__name__)
    app.config["SECRET_KEY"]="hard_to_guess_string"  #启动配置,设置密钥,表单内容通过加密传输
    
    class LoginForm(FlaskForm):     #设置网页表单类
        name=StringField("用户名:")       #字符输入框
        password=PasswordField("密码:")  #密码输入框
        submit=SubmitField("登录")        #提交按钮
        
    @app.route('/', methods=['GET', 'POST'])
    def index():
        form = LoginForm()          #表单类实例化
        if request.method=="POST":  #收到POST消息
            if form.name.data==form.password.data:  #自定义验证条件,使用户名、密码符合验证条件
                return render_template("text.html", s=form.name.data)
                #登录成功,往新页面传入用户名s
            else:
                return render_template("load.html",form=form)
                #登录失败,回到本页面
        else:
            return render_template("load.html",form=form)
    
    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

    注意:代码中使用 request.method == 'POST’接受按键按下后表单的返回值。课本上采用的是form.validate_on_submit()检测按键按下事件,两者效果基本等价。

    load.html内容:

    <html>
    <body>
    <h1>Load Form
    <form method="post">
         <p>{{form.name.label}} {{form.name}}p>
         <p>{{form.password.label}} {{form.password}}p>
         <p>{{form.submit}}p>
    form>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    text.html内容:

    <html>
    <body>
        <h1>登录成功!<h1>
        {% if s=="admin"%}
        <h1>Hello,Boss!h1>
        {%else%}
        <h1>Hello,{{s}}!h1>
        {%endif%}
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    浏览器登录页面(load.html)

    11

    表单中输入用户名为admin的效果(text.html):

    12

    表单中输入用户名为bob的效果(text.html):

    13
  • 相关阅读:
    HyperBDR云容灾深度解析二:自研Boot in Cloud技术,实现高度自动化云容灾
    十六、 代码校验(3)
    C语言:空指针野指针
    如何防止订单重复支付
    k8s入门之pod(四)
    Python基础
    华为云CodeArts IDE for Java安装使用教程
    禅道:提bug、管理case 7.0
    WebGPU学习(10)---如何利用 WebGPU 实现高性能
    贪心算法与DFS:九度OJ1030
  • 原文地址:https://blog.csdn.net/linmy3303/article/details/133417928