第一章 介绍、安装、快速使用、配置文件、路由系统、视图
Flask是一个基于Python开发并且依赖jinja2模板(DTL)和Werkzeug WSGI(符合wsgi协议的web服务器,wsgiref)服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用户复杂的内容时,需要借助jinja2模板来实现对模板的处理,即:将模板和数据进行渲染,将渲染后的字符串返回给用户浏览器。
flask是基于wsig协议的,所以部署的时候需要部署在符合wsgi协议的web服务器上
以下是一个简单的wsgiref示例代码:(flask就是基于wsgiref的)
from wsgiref.simple_server import make_server
def mya(environ, start_response):
print(environ)
start_response('200 OK', [('Content-Type', 'text/html')])
if environ.get('PATH_INFO') == '/index':
with open('templates/home.html', 'rb') as f:
data = f.read()
elif environ.get('PATH_INFO') == '/login':
with open('templates/login.html', 'rb') as f:
data = f.read()
else:
data = b'Hello, web!
'
return [data]
if __name__ == '__main__':
myserver = make_server('', 8011, mya)
myserver.serve_forever()
pip install flask
# 基础falsk搭建
from flask import Flask
app = Flask(__name__)
@app.route('/')
def login():
return 'hello world!'
if __name__ == '__main__':
app.run()
flask配置文件写法很多种
第一种写法:
直接对flask对象设置时,只能设置密钥和debug。
from flask import Flask
app = Flask(__name__)
app.secret_key='asfasdf'
app.debug=True
第二种:
app所有的配置项都在config这个字典中
通过键值对设置即可
app.config['DEBUG']=True
第三种:
编写一个py文件来进行配置
例如:
settings.py(编写配置文件一般用大写名称)
SECRET_KEY='asfasdf'
DEBUG = True
#将自行建立的settings.py设置到flask对象中
app.config.from_pyfile('settings.py')
第四种:
通过类来配置
class DevelopmentConfig():
secret_key = 'asdgf1231%%'
debug = True
#将设置好的类配置到flask对象中
app.config.from_object('settings.DevelopmentConfig')
其他方式:
例如创建一个json文件或者放到环境变量都是可以的。
flask 路由写法:
基于装饰器
from flask import Flask
app = Flask(__name__)
@app.route('/index', methods=['GET'], endpoint='index') # 第一个参数为url路径,第二个参数为请求方式,第三个为路由名称
def index():
return 'hello'
另一种写法(与django类似)
from flask import Flask
app = Flask(__name__)
@app.route('/index', methods=['GET'], endpoint='index') # 第一个参数为url路径,第二个参数为请求方式,第三个为路由名称
def index():
return 'hello'
app.add_url_rule('/index', view_func=index,)
转换器不设置类型时默认为default
转换器类型 | 获取到的值类型 |
---|---|
default | UnicodeConverter(传入什么类型数据就是什么类型) |
string | UnicodeConverter(传入什么类型数据就是什么类型) |
any | AnyConverter(任意类型) |
path | PathConverter (可以识别/的url类型) |
int | IntegerConverter(整数类型) |
float | FloatConverter(浮点数类型) |
uuid | UUIDConverter(uuid类型) |
例如:
@app.route('/index/' , methods=['GET'], endpoint='index') #默认类型转化器
def index(pk):
return 'hello'
@app.route('/index/' , methods=['GET'], endpoint='index') #指定类型转换器
def index(pk):
return 'hello'
从@app.route寻找源码,route会运行add_url_rule
@setupmethod
def route(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]:
def decorator(f: T_route) -> T_route:
endpoint = options.pop("endpoint", None)
self.add_url_rule(rule, endpoint, f, **options) #此处是重点
return f
return decorator
@setupmethod
def add_url_rule(
self, # 此处的self是app
rule: str,
endpoint: t.Optional[str] = None,
view_func: t.Optional[ft.RouteCallable] = None,
provide_automatic_options: t.Optional[bool] = None,
**options: t.Any,
) -> None:
def decorator(f: F) -> F:
self.view_functions[endpoint] = f
return f
return decorator
而app对象自身是没有add_url_rule方法的
运行时寻找add_url_rule方法是Flask类的
结合以上的代码分析
我们只需要自己实现add_url_rule方法即可完成路由的配置
#
app.add_url_rule('/order/' ,view_func=order)
app.add_url_rule('/index',view_func=index)
rule | 请求的路径,可以使用转换器 |
endpoint | 别名–》反向解析 |
view_func | 视图类.as_view(name=‘xx’)(视图函数内存地址) |
methods | 允许的请求方式 |
defaults | 字典,给视图函数传默认值 |
strict_slashes | 对URL最后的 / 符号是否严格要求 |
redirect_to | 重定向 |
flask的视图分为函数和类俩种
from flask import Flask, request, render_template, sessions, redirect
app = Flask(__name__)
app.secret_key = 'bbcasd##%9&^)[]'
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
else:
username = request.form.get('username')
password = request.form.get('password')
if username == 'kdq' and password == '123':
sessions['username'] = 'kdq'
return redirect('home.html')
else:
return render_template('login.html', error='用户名或密码错误')
cbv写法,继承MethodView,按照请求类型来命名对应的函数
from flask.views import MethodView
from flask import render_template, redirect
class Login(MethodView):
methods = ['GET', 'POST'] #设置该视图类允许的请求类型
def get(self):
return render_template('login.html')
def post(self):
return redirect('home.html')
#设置路由(可以把路由配置集成到一个py中)
app.add_url_rule('/login', view_func=Login.as_view(name='login')) # name它最终就是endpoint,但是必须写,即便写了endpoint
如果视图类继承了View,需要重写dispatch_request
from flask.views import View
from flask import render_template, redirect, Flask, request
class Login(View):
methods = ['GET', 'POST']
def get(self):
return render_template('login.html')
def post(self):
return redirect('home.html')
def dispatch_request(self):
if request.method == 'GET':
return self.get()
app = Flask(__name__)
app.add_url_rule('/login', view_func=Login.as_view(name='login'))
if __name__ == '__main__':
app.run()
cbv加装饰器, 在类中写 decorators = (装饰器名字,装饰器名字2,),第一个位置的会放在最下层,多个装饰器执行顺序是从上往下执行,加载顺序从下往上。
from flask.views import MethodView
from flask import render_template, redirect
class Login(MethodView):
methods = ['GET', 'POST'] #设置该视图类允许的请求类型
decorators = (islogin, xxxx) # 以元组的形式添加装饰器
def get(self):
return render_template('login.html')
def post(self):
return redirect('home.html')
#设置路由(可以把路由配置集成到一个py中)
app.add_url_rule('/login', view_func=Login.as_view(name='login'))