WEB应用开发-Flask第一天
一、WEB应用服务的认知
WEB应用服务基于HTTP协议/规范,实现静态资源和动态资源的请求与处理,静态资源包括html网页、图片、样式、JavaScript脚本、视频、音频等等。动态资源即通过程序(java/php/python/.net)和数据库(mysql/oracle/sqlserver)根据业务的处理流程会动态生成html,再将html响应给请求(客户端)。
HTTP(1.0,1.1,2.0)和HTML的关系:
1.客户端封装http请求(Http Request),向服务端发起请求
2.服务端接收请求之后,分析资源请求路径、请求参数(查询参数get、表单参数post)、请求方法、请求头等。
3.服务端根据资源请求路径读取文件内容,并生成字节码数据且封装响应对象
4.客户端接收服务端的响应数据(HttpResponse),判断请求是否成功,如果成功则显示数据(html/json)
WEB应用服务:
1.客户端(Browser浏览器)发起请求(HTTPRequest)
2.服务端(Apache/Nginx/PythonWeb)接收请求,根据请求的资源信息,读取文件,并封装到响应对象(HttpResponse)中
3.客户端接收资源,分析资源的类型然后渲染并显示出来。
另外,WEB应用服务基于HTTP协议,HTTP协议又于TCP/IP协议,因此是安全性连接。
二、Python Web开发框架
Python本身实现WEB应用服务的接口(规范),便于我们开发动态资源请求。提供的开发模块是wsgiref。此模块是所有其他高级框架中最核心的、最基本的规范、如Flask基于Werkzeug库实现了wsgi通信协议。
WSGI:Web Server Gateway Interface - Web服务网关接口,负责http协议的底层通信。
Python Web开发框架:Django(组件最全、最强大的框架,主要用于后端服务管理,运维(Ansible/OpenStack));
Flask小巧的、灵活的框架、可以快速开发API接口;
Tornado是基于协层和单线程单进程的框架实现非阻塞的网络框架;
Sanic是性能最优的WEB非阻塞框架。
Python wsgi案例:
from wsgiref.simple_server import make_server
def app(enviro, start_response):
# 生成响应对象
start_response('HTTP/1.1 200 OK',[('Content-type', 'text/html')]) # 响应头
return ['<h3>Hello,WSGI</h3>'.encode('utf-8')]
httpd = make_server('0.0.0.0', 8000, app)
httpd.server_forever(poll_interval=0.5) # 轮询监听的间隔时间
代码分析:
make_server() 是创建WEB服务进程。
app()函数的env是environment的简写,表示请求的环境信息,是dict字典类型。
三、Flask框架的应用
3.1 安装环境
(apiserver) > pip install flask -i https://mirrors.aliyun.com/pypi.simple
3.2 第一个Flask项目
创建sever2.py脚本。
from flask import Flask
# 创建Flask对象-Httpd WEB对象
app = Flask(__name__) # __name__ 可以是任意消息字母,表示Flask应用对象名称
# 声明WEB服务的请求资源(指定资源访问的路由)
# RESTful 设计风格中关于资源的动作:'GET','POST','CONNECT','DELETE','PUT','PATCH'
@app.route('/hello',methods=['GET','POST'])
def hello():
from flask import request
# request是请求对象(HttpRequest),包含请求资源的路径,请求方法,请求头,上传的表单数据,文件等信息。
# 获取请求中查询参数(username,password):
# wsgi-> QUERY_STRING:username= username=idsen&password=123
name = request.args.get('username')
password = request.args.get('password')
# 返回生成的HTML网页内容
return """
<h1>用户登录信息</h3>
<h3>用户名:%s</h3>
<h3>密码:%s</h3>
""" %(name,password)
# 启动flask的WEB服务器
app.run(host="0.0.0.0",port = 5000)
3.3Flask的MVC设计思想
1.客户端发起请求之后,通过路由找到视图处理函数
2.路由(请求资源)和视图处理函数(Controller)事先在app中声明中
3.在视图的处理函数中根据业务需求,加载数据(Model)并渲染到模板中(View)
4.将渲染之后的模板数据返回给客户端
3.4 Flask特有MTV设计思想
MTV设计思想,基于MVC的:
M-Model
T-Template模板(View)
V-View处理函数(Controller)
案例分析:
from flask import Flask
from flask import request,render_template
app = Flask('hiflask')
# 声明请求资源(动态资源)
@app.route('/hi', methods=['GET', 'POST'])
def hi():
# 使用request请求对象,获取请求方法
# 获取平台参数:platform
# 只支持Android 手机访问
platform = request.args.get('platform', 'PC')
if platform.lower() != 'android':
return """
<h2>目前只支持Android设备</h2>
"""
# GET 查询参数
if request.method == 'GET':
return """
<h1>用户登录页面</h1>
<form action='/hi' method='post'>
<input name="name" placeholder="用户名"><br>
<input name="pwd" placeholder="口令"><br>
<button>提交</button>
</form>
"""
else:
# 获取表单的参数,是字典类型,还有字典才有get方法
name = request.form.get('name')
pwd = request.form.get('pwd')
if all((
name.strip() == 'disen',
pwd.strip() == '987'
)):
return """
<h2 style="color:green;">登录成功</h2>
"""
else:
return """
<h2 style="color:red;">登录失败,<a href="/hi?platform=android">重试</a></h2>
"""
@app.route('/bank', methods=['GET', 'POST'])
def addBank():
# 加载数据(Model 交互操作)
data = {
'title':'绑定银行卡',
'error_message':'卡号和银行名称不能为空'
}
# 渲染模板
html = render_template('bank_edit.html',**data)
return html # 将数据返回给客户端
# 启动服务
app.run(host='0.0.0.0', port=5000)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>{{ title }}的页面</title>
</head>
<body>
<h2>{{ title }}的页面</h2>
<form>
<label>银行名称</label>
<input name="name"><br>
<label>卡号</label>
<input name="card_num"><br>
<button>提交</button>
</form>
<div class="error">
<span>{{ error_message }}</span>
</div>
</body>
</html>
以上的html文件不是静态的网页文件,而是一个动态的模板文件,页面中存在动态显示的变量。需要在视图函数中指定数据渲染模板,渲染之后的html内容才是静态资源。
3.4 app.run()
# 启动服务
app.run(host='0.0.0.0',
port=5000,
debug=True, # 默认未开启调试模式
threaded=True, # 默认是单线程
processes=1) # 默认只有一个进程
注意:多进程和多线程不能同时开启,只能选择一种。如:processes = 4,同时,threaded=True则会报错。