Windows 10 - Flask 框架 学习总结 1

目录

  • 一、环境配置安装
    • 安装 Virtualenv 虚拟环境
      • Virtualenv 虚拟环境内安装 Flask 框架
      • Tips:
  • 二、Flask 框架的初级学习
    • Flask 的 app 补充说明:
    • 运行 Flask 的最小应用(app)
      • (后期) 解决 Warning 报错,开启 WSGI 服务
    • 理解调试模式 app.run
    • 理解 Flask 框架的路由
      • 题外:Flask 框架 和 Django 框架的路由对比理解
    • 理解 Flask 路由URL尾部变量传参规则
    • 唯一 URL / 重定向行为
      • 什么是 Werkzeug :
      • 唯一 URL 及重定向规则案例
      • 唯一 URL 和 重定向 个人理解
    • Flask 框架自定义生成 URL 的 url_for()
      • 生成 URL 个人理解:
    • Flask 的 HTTP 请求方法 route('/',methods=[ ])
    • Flask 的\static\静态文件生成url_for('static', filename='test.css')
      • Flask 的静态文件访问个人理解 :
    • 解析客户端 Request 对象的参数
    • 处理表单Form的简单实例
    • 对 Flask Cookies 的设置与理解
      • 在Flask中对Cookie的处理步骤
        • set_cookie参数详解:

测试环境:

操作系统: Window 10
工具:Pycharm
Python: 3.7

一、环境配置安装

安装 Virtualenv 虚拟环境

使用 python 的框架,一般最好是弄一个虚拟环境,在虚拟环境内使用框架,这样比较方便后面的项目封装打包,而且可以对该项目运行环境与其他的项目的运行环境进行一个隔离,不会导致版本的冲突。
具体的看创建虚拟环境实操链接

Virtualenv 虚拟环境内安装 Flask 框架

cd 虚拟环境下的 Scripts 目录下

这样才可以调用虚拟环境内的 pip 指令下载 Flask 框架,而不是给本地下载 Flask 框架

pip install flask

Windows 10 - Flask 框架 学习总结 1_第1张图片
Flaskflask 大小写都可以

过程演练:
Windows 10 - Flask 框架 学习总结 1_第2张图片
Windows 10 - Flask 框架 学习总结 1_第3张图片

Tips:

最好在虚拟环境目录的Scripts目录下,安装Flask框架模块。

Flask 项目最好是手动创建虚拟环境,然后在Pycharm开发工具内创建Flask 项目,具体如下所示:
Windows 10 - Flask 框架 学习总结 1_第4张图片

上面红框内虚拟环境名\config 是在虚拟环境内新建的项目文件夹 configFlask项目的脚本文件都放在这里,下面的红框内的解释器路径是之前创建好的虚拟环境的python解释器的路径,注意这里指定好了(FlaskProject),而不是(FlaskProject)(1) 或 (FlaskProject)(2)、(FlaskProject)(3)…(FlaskProject)(n),这里就是 Pycharm 神奇的地方了,重复创建一个虚拟环境下的python解释器,让人感觉很难受,所以才强调要用手动创建虚拟环境。

创建结果:
Windows 10 - Flask 框架 学习总结 1_第5张图片

当然为什么坚持要使用虚拟环境,这是为了运行环境隔离,后期封装就简单多了。

二、Flask 框架的初级学习

Flask 的 app 补充说明:

对于 Flask 框架来说,一个 python 文件就是一个 app

运行 Flask 的最小应用(app)

最小应用代码演示:

# app.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
	return 'Hello World!'
	
if __name__ == '__main__':
	app.run()

保存为一个 app.py 脚本文件,当然需要注意的是以后给文件起名字,请确保你不会将它的文件名弄成 flask.py,这样会和 Flask 框架文件名冲突的。
运行 python 命令:(前面我弄了一个 FlaskProject 的 virtualenv 虚拟环境,后面就一直用这个虚拟环境,学习 Flask 框架)
这里分为两种运行方式:一种是Pycharm,另外一种是Windows 终端,不过这里就混合使用两种方式来测试,可以对比一下。

Pycharm运行

直接点击蓝色的URL,就可以自动弹出网页

Windows终端运行
在这里插入图片描述
终端运行成功,后在浏览器输入 127.0.0.1:5000 就可以看到结果 Hello World!
不过,看到红色的没有,警告 Warning,其实也没啥,只是 WSGI 没开启,这个模式用于开发环境调试,部署线上需要使用WSGI替代,所以这里就需要启动 WSGI 服务。

WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
警告:这是一个开发服务器。不要在生产部署中使用它。使用一个生产WSGI服务器代替。

解决方法:

参考链接:

https://blog.csdn.net/panruola/article/details/106012487

https://blog.csdn.net/GodDavide/article/details/103712131

https://www.cnblogs.com/mlp1234/p/13743254.html

http://www.wsmee.com/post/79

其实初学者,不建议一开始就按照我下面的做法,下面环节只是后期要做的,只是大致给个具体的做法而已。一般还是先用上面环节内的 app.run,正式环节才采用下面的开启 wsgi 服务器的做法。

(后期) 解决 Warning 报错,开启 WSGI 服务

安装 gevent 模块,导入 pywsgi,代码如下所示:

# hello.py
from flask import Flask
from gevent import pywsgi

app = Flask(__name__)

@app.route('/')
def hello_world():
	return 'Hello World!'
	
if __name__ == '__main__':
	server = pywsgi.WSGIServer(('0.0.0.0', 5000), app)
	server.serve_forever()

0.0.0.0 —— 这会让操作系统监听所有公网 IP。

结果如下:

这里就不会弹出类似这种的输出显示了
在这里插入图片描述
而是这种,好像没运行一样的空白终端。
Windows 10 - Flask 框架 学习总结 1_第6张图片
不过得在终端ipconfig 一下,找到自己 ip 地址,如果有多个 ip 地址,也没问题,反正只要是自己电脑所属的 ip 地址就行,就可以访问本机电脑服务器,然后随便输入自己电脑的 ip 地址 和 端口号,就可以了。这里可以弄一个测试用的静态 ip 地址,进行测试。
Windows 10 - Flask 框架 学习总结 1_第7张图片
终端会显示有如下的访问记录
Windows 10 - Flask 框架 学习总结 1_第8张图片

理解调试模式 app.run

虽然 run() 方法适用于启动本地的开发服务器,但是 你每次修改代码后都要手动重启它。这样并不够优雅,而且 Flask 可以做到更 好。如果你启用了调试支持,服务器会在代码修改后自动重新载入,并在发生 错误时提供一个相当有用的调试器。

有两种途径来启用调试模式。一种是直接在应用对象上设置:

# hello.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
	return 'Hello World!'
	
if __name__ == '__main__':
	app.debug = True
	app.run()

另一种是作为 run 方法的一个参数传入:

# hello.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
	return 'Hello World!'
	
if __name__ == '__main__':
	app.run(debug=True)

两种方法的效果完全相同。

debug - 是否开启调试模式并捕获异常

注意
尽管交互式调试器在允许 fork 的环境中无法正常使用(即在生产服务器上正常使用几乎是不可能的),但它依然允许执行任意代码。这使它成为一 个巨大的安全隐患,因此它 绝对不能用于生产环境

参考链接:
https://www.w3cschool.cn/flask_1/flask_1-74fv3ixu.html

app.run 个人理解:

app.run 提供一个调试模式供开发者去自行开发项目,这个 run方法,一般是用于开发环节使用的,而不是生产上线环节,而且由于有安全隐患,就更不能用于生产环境,此外,可以开启其调试模式,方便项目开发调试。

理解 Flask 框架的路由

URLUniform Resource Locator,统一资源定位器)能够用人所熟悉易于记忆的方式,来指向某个网站网页或文件,而不是用 ip 地址,这样的数字化思维去记忆,这是其很方便且极其重要的特点,我是这样理解的。

Flask 框架对于 URL 是一种绑定的思路,具体实现方法是利用一个 route() 的装饰器来绑定特定的 URL 与 指定的函数 / 方法,实现的代码如下:

# hello.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
	return 'Hello World!'
	
if __name__ == '__main__':
	app.run()
	

@ 符号后加 app.route() 等同于调用装饰器,来装饰下面某个 def 方法, 括号内指定某个 URL 字符串 ,下一行则是指定某个URL 特定函数 / 方法

题外:Flask 框架 和 Django 框架的路由对比理解

突然想来对比下两个框架的路由,没学过 Django 框架的,可以翻过了。

Django 框架的路由实现思路是 主路由表、子路由表及路由 URL 绑定;
Flask 框架的路由实现思路是 路由 URL 绑定;

这么一想,其实都是有共同点的,那就是路由 URL 绑定,都是通过路由 URL 绑定一个实现 URL 回传 html 的方法,只不过 Django 框架有着主路由表子路由表Flask 框架没有,仅仅是 路由 URL 绑定,有点像是精简了路由的 Django 框架。

理解 Flask 路由URL尾部变量传参规则

Flask 框架的 URL 内是可以传递变量的,该变量包括了传递用户名、表单的 id 号等等,而且这些变量是可以指定数据类型的,如整型、浮点型以及路径字符串

要给 URL 添加变量部分,你可以把这些特殊的字段标记为
这个部分将会作为命名参数传递到你的函数。规则可以用 \指定一个可选的数据类型转换器。这里有一些不错的例子:

@app.route('/user/')
def show_user_profile(username):
    # show the user profile for that user
    return 'User %s' % username

@app.route('/post/')
def show_post(post_id):
    # show the post with the given id, the id is an integer
    return 'Post %d' % post_id

转换器有下面几种:

类型 作用
int 接受整数
float int ,但是接受浮点数
path 和默认的相似,但也接受斜线

唯一 URL / 重定向行为

FlaskURL 规则基于 Werkzeug 的路由模块。这个模块背后的思想是基 于 Apache 以及更早的 HTTP 服务器主张的先例,保证优雅且唯一的 URL

什么是 Werkzeug :

首先,先向大家介绍一下什么是 WerkzeugWerkzeug是一个WSGI工具包,他可以作为一个Web框架底层库。这里稍微说一下, Werkzeug 不是一个web服务器,也不是一个web框架,而是一个工具包,官方的介绍说是一个 WSGI 工具包,它可以作为一个 Web框架的底层库,因为它封装好了很多 Web 框架的东西,例如 RequestResponse 等等。
其中 Flask 框架就是以 Werkzeug 为基础开发的

唯一 URL 及重定向规则案例

以这两个 URL 规则为例:

# hello.py
from flask import Flask
app = Flask(__name__)

@app.route('/test1/')
def urltest1():
	return '有斜线'

@app.route('/test2')
def urltest2():
	return '没有斜线'

	
if __name__ == '__main__':
	app.run(debug = True)

测试 1:

输入URL127.0.0.1:5000/test1/
Windows 10 - Flask 框架 学习总结 1_第9张图片
测试 2:

输入 URL127.0.0.1:5000/test1
Windows 10 - Flask 框架 学习总结 1_第10张图片
测试 3:

输入 URL127.0.0.1:5000/test2
Windows 10 - Flask 框架 学习总结 1_第11张图片
测试 4:

输入 URL127.0.0.1:5000/test2/
Windows 10 - Flask 框架 学习总结 1_第12张图片
参考引用:

第一种情况中,指向 projects 的规范 URL 尾端有一个斜线。这种感觉 很像在文件系统中的文件夹。访问一个结尾不带斜线URL 会被 Flask 重定向到带斜线的规范 URL 去。
然而,第二种情况的 URL 结尾不带斜线,类似 UNIX-like 系统下的文件的 路径名。访问结尾带斜线的 URL 会产生一个404 “Not Found” 错误。 这个行为使得在遗忘尾斜线时,允许关联的 URL 接任工作,与 Apache和其它的服务器的行为并无二异。此外,也保证了 URL唯一,有助于 避免搜索引擎索引同一个页面两次。

唯一 URL 和 重定向 个人理解

Flask 框架的路由 URL 绑定方法,一开始的路由 URL 绑定是否添加斜杠的区别是很大的,加斜杠了访问的是文件夹,不加斜杠的访问的是文件 —— 文件夹可以攘括了所有的文件,文件单单指的是某种类型的一个文件,文件夹可以补全斜杠,而文件无法补全斜杠
404 报错,也是因为找不到文件夹,定义为文件,那么自然不会有文件夹。

Flask 框架自定义生成 URL 的 url_for()

url_for() 来给指定的函数构造 URL。它接受函数名作为第一个 参数,也接受对应 URL 规则的变量部分的命名参数。未知变量部分会添加到 URL 末尾作为查询参数。

代码例子演示:

# app.py
from flask import Flask, url_for
app = Flask(__name__)

@app.route('/')		# 客户端请求的URL
def index(): 
	pass

@app.route('/login')	# 客户端请求的URL
def login(): 
	pass

@app.route('/user/')  # 客户端请求的URL
def profile(username): 
	pass

with app.test_request_context():	# 服务端回传的URL
	print(url_for('index'))		# 服务端回传的URL
	print(url_for('login'))		# 服务端回传的URL
	print(url_for('login', test='/'))		# 服务端回传的URL
	print(url_for('profile', username='John Doe'))		# 服务端回传的URL
	

运行结果:
Windows 10 - Flask 框架 学习总结 1_第13张图片
URL解析:

login 是无参数方法且作为 url_for() 的第一个参数,第二个参数,指的是URL,而 ? 后的未知变量部分,而且等于号 = 后为字符串形式’ ’ / " "

特别注意:URL是斜杠 / ,而Windows的文件路径是反斜杠 \

profile 是有参数方法,因为有参数,可以作为关键字参数传参,所以不像 login 那样,有一个 test 这样的 ? 未知变量部分,直接传递参数数值,无需添加 ? 未知变量部分

为什么你要构建 URL 而非在模板中硬编码?这里有三个绝妙的理由:

  1. 反向构建通常比硬编码的描述性更好。更重要的是,它允许你一次性修改 URL, 而不是到处边找边改。
  2. URL 构建会转义特殊字符和 Unicode 数据,免去你很多麻烦。
  3. 如果你的应用不位于 URL 的根路径(比如,在 /myapplication 下,而不 是 / ), url_for() 会妥善处理这个问题。

生成 URL 个人理解:

url_for() 这里是生成 URL 是一种灵活的方法,url_for() 绑定的是方法,返回值是route() 装饰器的 URL参数加上变量部分,从而生成的 URL 结果。这里要特别注意的一点是,方法,也就是函数,在绑定 URL 路由时,路由的名字,也就是斜杠 / 后的 URL 部分,是否要和方法同名,这一点得灵活一点,可以一样,我认为有时为了安全,需要不一样,如下所示:
Windows 10 - Flask 框架 学习总结 1_第14张图片

Flask 的 HTTP 请求方法 route(‘/’,methods=[ ])

浏览器的发送数据请求方法,是有好几种的不同的方法的,最常见的是 GETPOST —— GET 请求的内容是显示在 URL 这里,而 POST 请求请求的内容是放在请求的包内的,比较安全。

Flask 框架的 HTTP (与 Web 应用会话的协议)有许多不同的访问 URL 方法。默认情况下,路 由只回应 GET 请求,但是通过 route()装饰器传递 methods 参数可以改变这个行为。

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        do_the_login()
    else:
        show_the_login_form()

如果存在 GET ,那么也会替你自动地添加 HEAD,无需干预。它会确保 遵照 < a rel="nofollow" class="reference external" href="http://www.ietf.org/rfc/rfc2068.txt" rel="external nofollow" target="_blank" >HTTP RFC (描述 HTTP 协议的文档)处理HEAD 请求,所以你可以 完全忽略这部分的 HTTP 规范。同样,自从 Flask 0.6 起, 也实现了 OPTIONS 的自动处理。

这里只是大致介绍 HTTP 的常用一些方法,详情请自行搜索相关内容。

HTTP 方法(也经常被叫做“谓词” —— 动词 请求…)告知服务器,客户端想对请求的页面 些什么。自从 Flask 0.6起, 也实现了 OPTIONS 的自动处理。 下面的都是非常常见的方法:

GET

浏览器告知服务器:只获取页面上的信息并发给我。这是最常用的方法。

HEAD

浏览器告诉服务器:欲获取信息,但是只关心 消息头 。应用应像处理 GET 请求一样来处理它,但是不分发实际内容。在 Flask中你完全无需人工干预,底层的 Werkzeug 库已经替你打点好了。

POST

浏览器告诉服务器:想在 URL 上 发布 新信息。并且服务器必须确保 数据已存储且仅存储一次。这是 HTML表单通常发送数据到服务器的方法。

PUT

类似 POST 但是服务器可能触发了存储过程多次,多次覆盖掉旧值。你可能会问这有什么用,当然这是有原因的。考虑到传输中连接可能会丢失,在这种情况下浏览器和服务器之间的系统可能安全地第二次接收请求,而不破坏其它东西。因为 POST 它只触发一次,所以用 POST是不可能的可靠性问题,上传大文件,可以使用PUT

DELETE

删除给定位置的信息。

OPTIONS

给客户端提供一个敏捷的途径来弄清这个 URL 支持哪些 HTTP 方法。 从 Flask 0.6 开始,实现了自动处理。

简洁记忆:

也就是说 methods 的参数值是一个 list 列表,列表 list 里面的请求方法,都是一个字符串类型的数据。

有趣的是,在 HTML4XHTML1 中,表单只能以 GETPOST 方法提交到 服务器。但是 JavaScript 和未来的HTML 标准(如HTML 5)允许你使用其它所有的方法。此 外,HTTP 最近变得相当流行,浏览器不再是唯一的 HTTP 客户端。比如,许多版本控制系统就在使用 HTTP

Flask 的\static\静态文件生成url_for(‘static’, filename=‘test.css’)

动态 web 应用也会需要静态文件,通常是 CSSJavaScript 文件。理想状况下, 你已经配置好 Web服务器来提供静态文件,但是在开发中,Flask 也可以做到。 只要在你的包中或是模块的所在目录中创建一个名为 static 的文件夹,在应用中使用 /static 即可访问。

给静态文件生成 URL ,使用特殊的 'static' 端点名:

url_for('static', filename='style.css')

这个文件应该存储在文件系统上的 static/style.css

Flask 的静态文件访问个人理解 :

Flask 的静态文件默认是在 /static/ 的目录,在这个目录下,比如一些静态、动态图片、还有一些例如javascript文件或支持网页显示的CSS文件等等,都可以放在这里面,而首页这些html模板文件,就都放在 templates 目录下,并且使用方法 render_templates(html文件)Flask框架会在这个目录下查找html模板文件。

代码演示:

# app.py
from flask import Flask, render_template
app = Flask(__name__)

@app.route("/")
def index():
   return render_template("index.html")

if __name__ == '__main__':
   app.run(debug = True)

\templates\index.html 文件内容:

<html>

   <head>
      <script type = "text/javascript"
         src = "{{ url_for('static', filename = 'hello.js') }}" >script>
   head>

   <body>
      <input type = "button" onclick = "sayHello()" value = "Say Hello" />
   body>

html>

\static\hello.js 文件内容:

function sayHello() {
   alert("Hello World")
}

Windows 10 - Flask 框架 学习总结 1_第15张图片

运行结果:
Windows 10 - Flask 框架 学习总结 1_第16张图片

解析客户端 Request 对象的参数

来自客户端网页的数据作为全局请求对象发送到服务器。为了处理请求数据,应该从Flask模块导入。

Request对象的重要属性如下所列:

参数 功能
Form 它是一个字典对象,包含表单参数及其值的键和值对。
args 解析查询字符串的内容,它是问号(?)之后的URL的一部分。
Cookies 保存Cookie名称和值的字典对象。
files 与上传文件有关的数据。
method 当前请求方法

处理表单Form的简单实例

python代码文件:

# app.py
from flask import Flask, render_template, request
app = Flask(__name__)
@app.route('/')
def student():
   return render_template('student.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)
   

student.html 表单模板文件:

<form action="http://localhost:5000/result" method="POST">
     <p>Name <input type = "text" name = "Name" />p>
     <p>Physics <input type = "text" name = "Physics" />p>
     <p>Chemistry <input type = "text" name = "chemistry" />p>
     <p>Maths <input type ="text" name = "Mathematics" />p>
     <p><input type = "submit" value = "submit" />p>
form>

表单处理结果回传result.html模板文件

doctype html>
  <table border = 1>
     {% for key, value in result.items() %}
    <tr>
       <th> {{ key }} th>
       <td> {{ value }}td>
    tr>
 {% endfor %}
table>

运行结果:
Windows 10 - Flask 框架 学习总结 1_第17张图片
Windows 10 - Flask 框架 学习总结 1_第18张图片

对 Flask Cookies 的设置与理解

Cookie以文本文件的形式存储在客户端的计算机上。其目的是记住和跟踪与客户使用相关的数据,以获得更好的访问者体验和网站统计信息。

Request对象包含Cookie的属性。它是所有cookie变量及其对应值的字典对象,客户端已传输。除此之外,cookie还存储其网站的到期时间,路径和域名。

这说明Cookie能够设置登录连接时长和是否启用关闭浏览器等于关闭登录连接。

在Flask中对Cookie的处理步骤

  1. 设置客户端的cookie:
    设置cookie,默认有效期临时cookie,浏览器关闭就失效
    可以通过 max_age 设置有效期, 单位是秒

set_cookie参数详解:

set_cookie(cookie="",value="",max_age=None,expires=None,path="/",domain=None,secure=False,httponly=False)

cookie=““的名字(删除时也要使用)。
value=””, cookie的值
max_age=None,过期时间(单位为秒)。距离现在多少秒后cookie将过期。
expires=None, 为datetime类型。
path="/", 默认在‘/’ 表示在当前域名下的所有URL都有效。
domain=None, 设置cookie有效域名
secure=False, False表示在 http下使用, True表示在https下使用
httponly=False, True表示只能被浏览器读取,不能被js读取

设置回传给客户端 cookie 的相关配置

 resp = make_response("success")   # 设置响应体,成功创建了客户端cookie
 resp.set_cookie("test", "test", max_age=3600) # 创建 test cookie,时长1小时
 # 前面的"test"是cookie的键名,后面的是键值"test"
  1. 获取客户端的cookie
    获取cookie,通过request.cookies的方式, 返回的是一个字典,可以获取字典里的相应的值
cookie_1 = request.cookies.get("test")

可以从客户端请求中获取客户端的cookie信息

3.删除cookie
这里的删除只是让cookie过期,并不是直接删除cookie
删除cookie,通过delete_cookie()的方式, 里面是cookie的名字

resp = make_response("del success")  # 设置响应体,成功删除了客户端cookie
resp.delete_cookie("test")

对过期的 cookie 进行删除,否则过期的cookie还是会存在的。

完整代码演示:

from flask import Flask, make_response, request # 注意需导入 make_response

app = Flask(__name__)

@app.route("/set_cookies")
def set_cookie():
    resp = make_response("success")
    resp.set_cookie("cookiename", "cookievalue",max_age=3600)
    return resp

@app.route("/get_cookies")
def get_cookie():
    cookie_1 = request.cookies.get("cookiename")  # 获取名字为test对应cookie的值
    return cookie_1

@app.route("/delete_cookies")
def delete_cookie():
    resp = make_response("del success")
    resp.delete_cookie("test")

    return resp

if __name__ == '__main__':
    app.run(debug=True)
    

运行结果:
Windows 10 - Flask 框架 学习总结 1_第19张图片
Windows 10 - Flask 框架 学习总结 1_第20张图片

Windows 10 - Flask 框架 学习总结 1_第21张图片
测试下cookie还存不存在
Windows 10 - Flask 框架 学习总结 1_第22张图片
查看下删除cookie后,服务器的回传信息,按键盘上的F12
Windows 10 - Flask 框架 学习总结 1_第23张图片
Ctrl+R
Windows 10 - Flask 框架 学习总结 1_第24张图片
注意这里不是双击名称下的cookie,而是单击cookie。
Windows 10 - Flask 框架 学习总结 1_第25张图片

你可能感兴趣的:(windows,flask,学习)