Flask框架
1、初识flask
Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,
对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发
Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如
果要返回给用户复杂的内容时,需要借助jinja2模板来实现对模板的处理,即:将模板和数据
进行渲染,将渲染后的字符串返回给用户浏览器。
1.1 安装命令
pip install flask
2、flask的优势
- 轻型框架
- 可定制化
- 扩展性强
- 开发小型项目快。
3、初识werkzeug
werkzeug不是一个web框架,而是一个是一个WSGI的工具包,
它类似于Django的wsgiref,它可以作为Web框架的底层库,
因为它封装好了框架的东西。 例如:Request、Response等等。
但是在部署flask项目的时候,一般使用uwsgi或者gunicorn部署。
安装命令
pip install Werkzeug
示例:
from werkzeug.wrappers import Request, Response
@Request.application
def hello(request):
return Response('Hello World!')
if __name__ == '__main__':
from werkzeug.serving import run_simple
run_simple('localhost', 5000, hello)
正是因为Werkzeug本质是Socket服务端,当请求来了会触发hello函数加括号执行,而flask中的app.run()中同样使用run_simple(host, port, self, **options)
,当实例化app对象时会将app当做参数传入,执行__call__
方法,__call__
方法本质还是调用了self.wsgi_app(environ, start_response)
,这是整个web程序的入口。
4、第一个flask
from flask import Flask
# 实例化产生一个Flask对象
# import_name Flask程序所在的包(模块),传 __name__ 就可以其可以决定 Flask 在访问静态文件时查找的路径
# static_path 静态文件访问路径(不推荐使用,使用 static_url_path 代替)
# static_url_path 静态文件访问路径,可以不传,默认为:/ + static_folder
# static_folder 静态文件存储的文件夹,可以不传,默认为 static
# template_folder 模板文件存储的文件夹,可以不传,默认为 templates
app = Flask(__name__) # __name__这里是__main__
# 将 '/'和视图函数hello_workd的对应关系添加到路由中
@app.route('/') # 1. v=app.route('/') 2. v(hello_world)
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run() # 最终调用了run_simple()
总结:
- 当请求来了会触发app(),然后触发
app.__call__()
将两个参数传入,一个是environ
另一个是start_response
,其实Werkzeugde
的本质还是wsgi
的实现。
5、登录显示用户信息
示例:
- main.py
from flask import Flask,render_template,request,redirect,session,url_for
app = Flask(__name__)
app.debug = True
app.secret_key = 'sdfsdfsdfsdf'
USERS = {
1:{'name':'张三','age':18,'gender':'男','text':"道路千万条"},
2:{'name':'李四','age':28,'gender':'男','text':"安全第一条"},
3:{'name':'王五','age':18,'gender':'女','text':"行车不规范"},
}
@app.route('/detail/<int:nid>',methods=['GET'])
def detail(nid):
user = session.get('user_info')
if not user:
return redirect('/login')
info = USERS.get(nid)
return render_template('detail.html',info=info)
@app.route('/index',methods=['GET'])
def index():
user = session.get('user_info')
if not user:
# return redirect('/login')
url = url_for('l1')
return redirect(url)
return render_template('index.html',user_dict=USERS)
@app.route('/login',methods=['GET','POST'],endpoint='l1')
def login():
if request.method == "GET":
return render_template('login.html')
else:
# request.query_string
user = request.form.get('user')
pwd = request.form.get('pwd')
if user == 'cxw' and pwd == '123':
session['user_info'] = user
return redirect('http://www.baidu.com')
return render_template('login.html',error='用户名或密码错误')
if __name__ == '__main__':
app.run()
总结:
0 当次请求的对象,request对象是全局的,直接导入使用即可
1 前端post提交的数据,从flask中的:request.form中取
2 转换器的使用/detail/<int:pk>
3 模板语法兼容django的dtl,可以直接使用函数加括号,并且可以传参数
4 session也是全局对象,用户登录信息,放到session中
5 新手四件套
字符串 ---> HttpResonse('字符串')
redirect('/') ---> redirect('/')
render_template()---> render()
jsonify ----> JsonResponse()
5 前端get请求提交的数据,从request.args
6 request.query_string是get请求 ? 后面的内容,bytes格式
7 @app.route('/detail', methods=['GET'],endpoint='detail')
endpoint等同于django路由中的name别名
- detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>详细信息 {{info.name}}</h1>
<div>
{{info.text}}
</div>
</body>
</html>
- index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>用户列表</h1>
<table>
{% for k,v in user_dict.items() %}
<tr>
<td>{{k}}</td>
<td>{{v.name}}</td>
<td>{{v['name']}}</td>
<td>{{v.get('name')}}</td>
<td><a href="/detail/{{k}}">查看详细</a></td>
</tr>
{% endfor %}
</table>
</body>
</html>
- login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>用户登录</h1>
<form method="post">
<input type="text" name="user">
<input type="text" name="pwd">
<input type="submit" value="登录">{{error}}
</form>
</body>
</html>
6、flask的配置文件
# flask.config.Config
方式一:直接写app.config['DEBUG'] 一般不用
方式二:放到py文件中 一般不用
方式三:通过环境变量 一般不用
app.config.from_envvar("环境变量名称")
app.config.from_json("json文件名称")
JSON文件名称,必须是json格式,因为内部会执行json.loads
app.config.from_mapping({'DEBUG': True})
方式四: 通过类的方式 用的多
app.config.from_object('settings.DevelopmentConfig')