WEB开发是现在程序必会的技能,因为大部分软件都以Web形式提供,及时制作后台开发,或者只做前台开发,也需要了解Web开发的概念和特点。由于Python是解释性脚本语言,用来做Web开发非常适合,而且Python有上百种Web开发框架,以及成熟的模板技术,使得Web开发如虎添翼。今天借用Flask框架,快速学习一下Python的Web开发知识。
Flask框架
Flask的设计易于使用和扩展。它的初衷是为各种复杂的Web应用程序构建坚实的基础。可以自由地插入任何扩展。也可以自由构建自己的模块。Flask适合各种项目。它对原型设计特别有用。Flask依赖于两个外部库:Jinja2模板引擎和Werkzeug ? WSGI工具包。Flask是最精致,功能最丰富的微框架之一。Flask还很年轻,拥有蓬勃发展的社区,一流的扩展和漂亮的API。Flask具有快速模板,强大的WSGI功能,在Web应用程序和库级别的完整单元可测性,以及大量文档等优点。选用Flask框架也是因为它方便入手,结构简单,零配置,是个学习Python ?Web开发的好工具。
安装Flask
像其他模块一样,Flask的安装很简单,下面通过pip包管理器来安装
pip?install?flask
检查一下是否安装正确 在命令行下输入 python 进入命令行模式 引入flask模块 回车
>>>?import?flask>>>
如果没有错误提醒,就说明安装成功了
Hello world
下面写个最简单的Web应用 hello.py
from?flask?import?Flask??#?引入Flask模块 app?=?Flask(__name__)?#?创建一个应用 @app.route('/') def?index():????#?定义根目录处理器 ????return?'<h1>Hello?World!</h1>' ???? if?__name__?==?'__main__': ????app.run()?#?启动服务
打开终端,跳转到 hello.py 文件所在的文件夹,进入python命令行模式,启动服务
>>>?python?hello.py
如果一起正常的话会有类似下面的反馈
?*?Serving?Flask?app?"hello"?(lazy?loading)?*?Environment:?production???WARNING:?This?is?a?development?server.?Do?not?use?it?in?a?production?deployment.???Use?a?production?WSGI?server?instead.?*?Debug?mode:?off?*?Running?on?http://127.0.0.1:5000/?(Press?CTRL+C?to?quit)
因为是通过 app.run() 启动的服务,所以会有个错误提示,提醒不能将此Web应用部署在生产环境中,可以暂时忽略
此时,打开浏览器,输入 127.0.0.1:5000/ 或者 localhost:5000/, 就可以看到 Hello World!欢迎字样。
路由
路由是Web开发中一个很重要的概念,用来将不同的请求,映射到响应的处理方法上,这个方法被称为 视图函数 。比如刚才的 Hello 应用,将根请求,映射到 index 处理方法上,下面简单了解下Flask对路由的支持 Flask通过修饰器(和Java的注解类似)来建立路由映射关系的,已经看到修饰器是 app.rotue()
简单路由如 访问 /hello
@app.route('/hello')def?hello():????return?'Hello!'动态路由
如访问 /user/bob 或者 /user/lily 都会映射到同一视图函数上
@app.route('/user/<name>')def?user(name):????return?'<h1>Hello,?%s!?</h1>'?%?name
动态域名中动态的部分可以作为视图函数的参数,也支持多个动态参数,如访问 /user/bob/23
@app.route('/user/<name>/<age>')def?user(name,?age):????return?"<h1>?Hello,?%s,?you're?%s?years?old"?%?(name,?age)
还可以指定动态部分的数据类型,如
@app.route('/post/<int:post_id>') def show_post(post_id): ? ?# show the post with the given id, the id is an integer ? ?return 'Post %d' % post_id @app.route('/path/<path:subpath>') def show_subpath(subpath): ? ?# show the subpath after /path/ ? ?return 'Subpath %s' % escape(subpath)
支持的数据类型
类型 说明 string (默认值) 任何不包含斜杠的文本 int 正整数 float 正浮点数 path 类似?string?,但可以包含斜杠 uuid 接受 UUID 字符串 指定HTTP 方法HTTP协议,支持多种HTTP 方法,例如 HEAD 、 OPTIONS ,以及常用的 GET 、 POST 等,Flask自动处理了 HEAD 和 OPTIONS ,路由默认接受的方法是GET,如果要匹配其他请求方法,可以在路由方法的 methods 参数来指定
@app.route('/login',?methods=['GET',?'POST'])def?login():????if?request.method?==?'POST':????????return?do_the_login()????else:????????return?show_the_login_form()复合路由
也可以将多个路由规则,用于一个视图函数, 如访问 /job/ 和访问 /work/ 效果是一样的
@app.route('/job/')@app.route('/work/')def?show_works():????return?'This?is?works?page'
再复杂一点的例子
@app.route('/users/',?defaults={'page':?1})@app.route('/users/page/<int:page>')def?show_users(page):????pass
上面的代码表示,当访问 /user/ 或者 /user/page/<pageindex> 时,都会有 show_users 视图函数来处理, 而且还为 /user/ 提供了默认值,即访问 /user/ 相当于访问 /user/page/1
请求和响应
Web应用,最重要的事情就是处理接收到的请求,并返回响应。Flask框架也一样,它提供了请求对象 request 和响应对象 response ,可以方便的在视图函数中使用。
请求Flask将客户端发送的HTTP请求封装成了 request 请求对象,并且使用上下文(context)临时将 request 变为全局可访问的,于是在视图还是中,就可以直接使用了。
注意 : request 并非真正的全局变量!试想,在多线程服务器中,多个线程同时处理不同客户端发送的不同请求时,每个线程看到的 request 对象必然不同。Falsk使用上下文让特定的变量在一个线程中全局可访问,与此同时却不会干扰其他线程。
Flask有两种上下文,分别为程序上下文和请求上下文,各自对应的全局变量如下表:
变量名 上下文类型 备注 current_app 程序上下文 表示当前运行的程序实例 g 程序上下文 处理请求时用作临时存储对象,每次请求都会重新设值 request 请求上下文 客户端发来的request请求对象 session 请求上下文 请求携带的会话信息使用 request 对象前,需要先引入
from?flash?import?request
request 对象提供了丰富的属性和方法,这里举个例子:通过使用? method ?属性可以操作当前请求方法,通过使用? form ?属性处理表单数据(在? POST ?或者? PUT ?请求 中传输的数据)。以下是使用上述两个属性的例子:
@app.route('/login',?methods=['POST',?'GET'])def?login():????error?=?None????if?request.method?==?'POST':????????if?valid_login(request.form['username'],???????????????????????request.form['password']):????????????return?log_the_user_in(request.form['username'])????????else:????????????error?=?'Invalid?username/password'????#?the?code?below?is?executed?if?the?request?method????#?was?GET?or?the?credentials?were?invalid????return?render_template('login.html',?error=error)
注意 :当 form 属性中不存在这个键时会发生什么?会引发一个 KeyError 。如果不处理这个错误?,就会显示一个 HTTP 400 Bad Request 错误页面。
如果要操作 URL (如??key=value?)中提交的参数可以使用?args?属性,如 : searchword = request.args.get('key', '')
请求钩子有时在处理请求之前或之后执行代码会很有用。例如,在请求开始时,可能需要创建数据库连接或者认证发起请求的用户。为了避免在每个视图函数中都使用重复的代码,Flask提供了注册通用函数的功能,注册的函数可在请求被分发到视图函数之前或之后调用。请求钩子使用修饰器实现。Flask支持以下4种钩子:
before_first_request :注册一个函数,在处理第一个请求之前运行。
before_request :注册一个函数,在每次请求之前运行。
after_request :注册一个函数,如果没有未处理的异常抛出,在每次请求之后运行。
teardown_request :注册一个函数,即使有未处理的异常抛出,也在每次请求之后运行。
示例: 在接受到第一个请求是,打印一句话:
@app.before_first_requestdef?first_quest():????print("run?before?first?request")
在请求钩子函数和视图函数之间共享数据一般使用上下文全局变量g。 例如,before_request处理程序可以从数据库中加载已登录用户,并将其保存到g.user中。随后调用视图函数时,视图函数再使用g.user获取用户。
响应响应是Web服务器对请求的一个回应,在Flask中,有多种形式的响应。视图函数的返回值会自动转换为一个响应对象。如果返回值是一个字符串,那么会被 转换为一个包含作为响应体的字符串、一个 200 OK 出错代码 和一个? text/html ?类型的响应对象。如果返回值是一个字典,那么会调用? jsonify() ?来产生一个响应。以下是转换的规则:
如果视图返回的是一个响应对象,那么就直接返回它。
如果返回的是一个字符串,那么根据这个字符串和缺省参数生成一个用于返回的 响应对象。
如果返回的是一个字典,那么调用? jsonify ?创建一个响应对象。
如果返回的是一个元组,那么元组中的项目可以提供额外的信息。元组中必须至少 包含一个项目,且项目应当由? (response,?status) ?、? (response,?headers) ?或者? (response,?status,?headers) ?组成。? status ?的值会重载状态代码,? headers ?是一个由额外头部值组成的列表 或字典。
如果以上都不是,那么 Flask 会假定返回值是一个有效的 WSGI 应用并把它转换为 一个响应对象。
除此之外,还可以通过 make_response() 函数,创建可以响应对象,做更个性的事情。
使用 make_response() 前,需要先引入
from?flask?import?make_response
示例:
响应有元组构成
@app.errorhandler(404)def?not_found(error):????return?render_template('error.html'),?404
@app.errorhandler 修饰符,会将一个响应代码映射到一个视图函数上,这里是将404(找不到页面)码,处理成一个个性的错误页面 另外, render_template 是Flask的模板函数,简单理解就是格式化一个动态的html字符串,关于模板的详细用法,会在模板章节描述
使用?make_response()?包裹返回表达式,获得响应对象,并对该对象 进行修改,然后再返回:
@app.errorhandler(404)def?not_found(error):????resp?=?make_response(render_template('error.html'),?404)????resp.headers['X-Something']?=?'A?value'????return?resp
总结
本文借助Flask框架,简要介绍了下Python Web开发的基本知识和技术,希望能帮助您快速入门,在Python学习的道路上走的更顺畅。后续还会将就Web开发的话题,对 模板 、 数据库 以及扩展功能等进行讲解,敬请期待!
参考
图书: Flask Web开发 [1]
Flask快速上手 [2]
Flask入门到精通(二) [3]
Web服务器网关接口 [4]
参考资料
[1]图书: Flask Web开发: https://item.jd测试数据/12418677.html
[2]Flask快速上手: https://dormousehole.readthedocs.io/en/latest/quickstart.html
[3]Flask入门到精通(二): https://HdhCmsTestcnblogs测试数据/java-wgm/p/6602900.html
[4]Web服务器网关接口: https://zh.wikipedia.org/wiki/Web%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%BD%91%E5%85%B3%E6%8E%A5%E5%8F%A3
系列文章
??第18天:Python 之迭代器? ? ??第17天:Python 之引用? ? ? 第16天:Python 错误和异常?? ?? 第15天:Python 输入输出
?
??第14天:Python 高阶函数
?
??第13天:Python 函数的参数?
?
??第12天:Python 集合
?
??第11天:Python 字典第10天:Python 类与对象
第9天:Python?Tupple
第8天:Python List
第7天:Python 数据结构--序列
第6天:Python 模块和包
第5天:Python 函数
第4天:Python 流程控制
第3天:Python 变量与数据类型
第2天:Python 基础语法
第1天:Python 环境搭建
查看更多关于第19天:Web 开发 Flask 介绍的详细内容...