Chybeta

Flask Web开发笔记(1):程序的基本结构

最近跟着狗书flask文档学习Flask。结合官方文档对一些知识点做一些笔记,并做一些适当扩展。所以不太成体系甚至很零散,勿喷。

初始化

Flask程序必须要创建一个程序实例,程序实例是Flask类的对象。如下:

1
2
from flask import Flask
app = Flask(__name__)

对于该Flask类,其定义如下:

1
class flask.Flask(import_name, static_path=None, static_url_path=None, static_folder=’static’, template_folder=’templates’, instance_path=None, instance_relative_config=False, root_path=None)

第一个参数是必须要指定的。Flask用这个参数来找到相对于程序根目录的资源文件位置。如果是使用单一的模块(module),使用__name__就行了。如果是使用一个包(package)的话,推荐硬编码进去。

路由和视图函数

flask程序实例保存了一个URL到python函数的映射关系。当客户端发送请求,服务器将请求转发给flask程序实例,flask程序实例依照映射关系利用函数进行处理。处理URL和函数之间的关系称之为路由。而像下文的index()hello()的处理函数,称之为视图函数。

可以使用app.route修饰器来定义路由。(注:这里的app是前面已经创建好了的Flask类的对象)。

基本示例:

1
2
3
4
5
6
7
@app.route('/')
def index():
return "hello world!"
@app.route('/hello')
def hello():
return "hello hello world!"

在默认情况下,访问http://localhost:5000/时页面会打印出hello,world!,当访问http://localhost:5000/hello时,页面则会打印出hello hello world!。

也可以构造动态的URL。通过给URL加上变量,利用装饰器,可以对URL的变量来做出对应的变化。这些动态的部分/变量,需要被标记为<variable_name>或者<converter:variable_name>,这个部分将可以被作为命名参数传递到函数中。

1
2
3
4
5
6
7
@app.route('/<name>')
def user(name):
return "I'm %s" % name
@app.route('/<int:id>')
def userid(id):
return "The isinstance(id,int): %s" % isinstance(id,int)

访问:http://localhost:5000/chybeta,会将字符串chybeta传递到user函数中,并返回给客户都:I’m chybeta。

若是访问:http://localhost:5000/1 则:

在第二个例子中:@app.route('/<int:id>'),指定了一个转换器,将id转换为整型int。目前有以下几种转换器:

类型 说明
string 默认。接受除了斜杠以外的文本
int 接受整数
float 同 int ,但是接受浮点数
path 和默认的相似,但也接受斜线
any matches one of the items provided
uuid 接受uuid字符串

path选择器的作用如下:

1
2
3
@app.route('/<path:paths>')
def path(paths):
return "The path: %s" % paths

也就是说,path选择器不会把斜线作为分隔符,而是作为匹配的一整个部分。

any选择器,未知,哪位解释下?

uuid,如下:

1
2
3
@app.route('/<uuid:id>')
def uuid(id):
return "The uuid: %s" % id

flask的Web服务器

在前面定义好程序实例app后,可以用run()方法来启动flask自带的Web服务器。

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

run()方法的定义如下:

1
run(host=None, port=None, debug=None, **options)

在 debug 模式启用的情况下(debug=True),服务器会对修改的代码自动重新加载。

另外,这个本身的服务器并不适用于生产环境。详情可见:Deployment Options

请求与响应循环

程序与请求上下文

1
2
3
4
5
6
from flask import request
@app.route('/')
def index():
user_agent = request.headers.get('User-Agent')
return '<p>Your brower is %s</p>' % user_agent

这里出现了一个request类。关于其介绍可以见这里。对于传入的request数据,flask保存了一个全局变量request对象。在一个多线程的环境中,flask能确保特定的request对象在特定的线程中全局可访问。

有一些较为常用的attributes:

  1. request.headers: 以字典形式保存保存了request的头部。。

  2. request.method:指明了是GET还是POST方法等。

  3. request.cookies: 以字典形式保存了cookie
  4. …. 还有好多 遇到再补充。

请求调度

接前面的URL映射关系与路由。除了使用app.route()修饰器来注册为事件的处理程序外,还有另外两种:

  1. flask.Flask.add_url_rule()
  1. flask.Flask.url_map

这里不展开,详细可见URL Route Registrations

请求钩子

响应

Flask扩展

微信扫码加入知识星球【漏洞百出】
chybeta WeChat Pay

点击图片放大,扫码知识星球【漏洞百出】