WEB开发是如今程序必会的技能,由于大部分软件都以Web形式提供,及时制做后台开发,或者只作前台开发,也须要了解Web开发的概念和特色。因为Python是解释性脚本语言,用来作Web开发很是适合,并且Python有上百种Web开发框架,以及成熟的模板技术,使得Web开发如虎添翼。今天借用Flask框架,快速学习一下Python的Web开发知识。html
Flask的设计易于使用和扩展。它的初衷是为各类复杂的Web应用程序构建坚实的基础。能够自由地插入任何扩展。也能够自由构建本身的模块。Flask适合各类项目。它对原型设计特别有用。Flask依赖于两个外部库:Jinja2模板引擎和Werkzeug WSGI工具包。Flask是最精致,功能最丰富的微框架之一。Flask还很年轻,拥有蓬勃发展的社区,一流的扩展和漂亮的API。Flask具备快速模板,强大的WSGI功能,在Web应用程序和库级别的完整单元可测性,以及大量文档等优势。选用Flask框架也是由于它方便入手,结构简单,零配置,是个学习Python Web开发的好工具。java
像其余模块同样,Flask的安装很简单,下面经过pip包管理器来安装python
pip install flask
检查一下是否安装正确 在命令行下输入 python
进入命令行模式 引入flask模块 回车数据库
>>> import flask>>>
若是没有错误提醒,就说明安装成功了json
下面写个最简单的Web应用 hello.py
flask
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应用部署在生产环境中,能够暂时忽略session
此时,打开浏览器,输入 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 方法,例如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]
图书: Flask Web开发: https://item.jd.com/12418677.html
[2]Flask快速上手: https://dormousehole.readthedocs.io/en/latest/quickstart.html
[3]Flask入门到精通(二): https://www.cnblogs.com/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
系列文章
第11天:Python 字典