【无标题】

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

作者:

文章目录

  • flask工具书-搭建一个简单Web应用
  • 1.第一个WEB服务
  • 2.路由传递信息
    • 2.1获取信息
    • 2.2简单应用
  • 3.GET/POST传递信息
    • 3.1GET
    • 3.2POST
  • 4.总结
  • 5.其他知识
    • 5.1 Html基础语法
      • 5.1.1HTML 标签
      • 5.1.2HTML结构
      • 5.1.3 常用语法
    • 5.2 了解SQL
  • 6.拓展1_Jinja2模板
    • 6.1基础模板
    • 6.2Jinja2模板调用
  • 7.拓展2_表单
    • 7.1Flask处理通用表单(在html中书写静态表单)
    • 7.2Flask_wtf的使用(html接收来自代码的动态表单)

网络框架是一种工具,用于快速和容易地开发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()

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

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

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

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()

现在我们向浏览器的地址栏中输入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()

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

[外链图片转存中…(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()

[外链图片转存中…(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()

index.html中的内容

<form action="/login" method="post">
    <p>用户名p>
    <p><input type="text" name="user" />p>
    <p><input type="submit" value="确定"/>p>
form>

[外链图片转存中…(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的缩写,代表超文本引用。

任意文本

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

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

定义图像的语法是:


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

换行:br是break的缩写


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'))

例如上方的代码,就是向数据表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()

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

 <h1>欢迎您h1>

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

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()

html内容

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

运行结果:

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

7.拓展2_表单

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

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

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

关键属性:

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)

index.html内容:

GET方法提交表单数据

姓名:

性别:

POST方法提交表单数据

姓名:

性别:

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

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("登录")        #提交按钮

表单类实例化

form = LoginForm()

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

<form>
     <p>用户名:<input type="text" name="name">p>
     <p>密码:<input type="password" name="password">p>
     <p><input type="submit" value="登录">p>
form>

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)

注意:代码中使用 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>

text.html内容:

<html>
<body>
    <h1>登录成功!<h1>
    {% if s=="admin"%}
    <h1>Hello,Boss!h1>
    {%else%}
    <h1>Hello,{{s}}!h1>
    {%endif%}
body>
html>

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

11

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

12

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

13

你可能感兴趣的:(python,python,经验分享,flask,web,app)