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

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

[外链图片转存中…(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/<name>')
def hello(name):
    return 'Hello ' + name

@app.route('/user/<int:user_id>')
def get_user(user_id):
    return 'User ID: ' + str(user_id)

@app.route('/content/<username>/<password>/')
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/<int:book_id>')
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的缩写,代表超文本引用。

<a href="http://www.baidu.com">任意文本</a>

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

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

定义图像的语法是:

<img src="url" >

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

换行:br是break的缩写

<br>

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内容:

<p>GET方法提交表单数据</p>
<form action="/success" method="get">
       <p>姓名:<input type="text" name="name"></p>
       <p>性别:<input type="radio" name="sex" value="male" checked>男
               <input type="radio" name="sex" value="female">女</p>
       <p><input type="submit"  value="提交"> </p>
</form>

<p>POST方法提交表单数据</p>
<form action="/success" method="post">
       <p>姓名:<input type="text" name="name"></p>
       <p>性别:<input type="radio" name="sex" value="male" checked>男
               <input type="radio" name="sex" value="female">女</p>
       <p><input type="submit"  value="提交"> </p>
</form>

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 以下是一个基本的 U-Boot 脚本,用于配置 SPI Flash。该脚本使用 `sf probe` 命令探测 SPI Flash 设备,然后设置 U-Boot 环境变量来存储 Flash 设备的参数。请注意,此示例中的参数值需要根据您的 Flash 设备进行更改。 ``` # 定义 Flash 设备参数 setenv spi_flash_addr 0x0 # Flash 设备地址 setenv spi_flash_size 0x800000 # Flash 设备大小 # 探测 Flash 设备 sf probe # 将 Flash 设备参数存储到环境变量中 setenv bootargs root=/dev/mtdblock0 rootfstype=jffs2 rw setenv bootcmd 'sf read ${loadaddr} ${spi_flash_addr} ${spi_flash_size}; bootm' saveenv ``` 在这个例子中,`spi_flash_addr` 表示 Flash 设备的起始地址,`spi_flash_size` 表示 Flash 设备的大小。`sf probe` 命令用于探测 SPI Flash 设备,并且将 Flash 设备参数存储到 U-Boot 环境变量中。最后,`bootcmd` 环境变量定义了如何从 Flash 设备启动系统。 ### 回答2: 以下是一个使用u-boot脚本配置SPI闪存的示例: ``` # 使用U-Boot脚本配置SPI闪存示例 # 首先,我们需要加载SPI闪存驱动 # 根据硬件版本和芯片型号进行适配 # 这里我们以Spansion SPI闪存为例 sf probe # 然后,我们需要设置闪存的相关参数 # 首先是闪存器件的名称 setenv spi_flash_name "spansion" # 接下来是闪存器件的页大小 # 这里以256字节为例 setenv spi_flash_page_size 256 # 然后是扇区大小 # 这里以4KB为例 setenv spi_flash_sector_size 4096 # 最后是闪存总大小 # 这里以32MB为例 setenv spi_flash_total_size 32M # 配置完成后,可以将相关参数保存到环境变量中 saveenv # 如果需要擦除整个闪存,可以使用以下命令 sf erase 0 ${spi_flash_total_size} # 如果需要读取闪存中的数据,可以使用以下命令 sf read ${loadaddr} 0 ${filesize} # 如果需要将数据写入闪存,可以使用以下命令 sf write ${loadaddr} 0 ${filesize} # 使用以上命令和参数,我们可以在U-Boot环境中配置和操作SPI闪存。 ``` 请注意,实际的配置和操作可能因硬件和芯片型号不同而有所不同。以上示例仅供参考,具体操作步骤和参数应根据实际情况进行适配。 ### 回答3: 下面是一个示例的u-boot脚本配置SPI Flash的例子: ``` # 定义相关环境变量 setenv spi_flash_addr 0x1000000 # SPI Flash起始地址 setenv kernel_image_addr 0x200000 # 内核镜像在内存中的加载地址 setenv dtb_addr 0x400000 # 设备树在内存中的加载地址 # 配置SPI Flash sf probe 0:0 # 扫描并初始化第0个SPI Flash设备 sf erase ${spi_flash_addr} 0x100000 # 擦除SPI Flash的前1MB空间 # 将内核镜像和设备树加载到内存中 tftp ${kernel_image_addr} kernel.img # 从TFTP服务器下载内核镜像 tftp ${dtb_addr} device_tree.dtb # 从TFTP服务器下载设备树 # 将内核镜像和设备树写入SPI Flash sf write ${kernel_image_addr} ${spi_flash_addr} 0x100000 # 将内核镜像写入SPI Flash的第1MB位置 sf write ${dtb_addr} ${spi_flash_addr} 0x200000 # 将设备树写入SPI Flash的第2MB位置 # 设定内核启动参数 setenv bootargs 'console=ttyS0,115200 root=/dev/mtdblock2 rootfstype=jffs2' # 启动内核 bootm ${kernel_image_addr} - ${dtb_addr} ``` 这个例子展示了如何使用u-boot脚本配置SPI Flash。首先定义了SPI Flash的起始地址,并擦除了前1MB的空间。然后从TFTP服务器下载内核镜像和设备树,并将它们写入SPI Flash的相应位置。接着设置内核启动参数,并最后启动内核。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值