概述:Django与Flask的区别
Django是一个大而全的框架,Flask是一个轻量级的框架;
Django内部为我们提供了非常多的组件:orm/session/cookie/admin/form/modelform/视图/路由/模板/中间件/分页/auth(认证)/contenttype/缓存/信号/多数据库连接 等。
Flask框架本身没有太多功能:路由/视图/模板(jinja2)/session,第三方组件非常齐全。
注意:Django的请求处理是逐一封装并传递,Flask的请求是利用上下文管理来实现的。(请求会被放在特殊的地方,需要请求时去特定的地方取)
Flask快速使用
安装
pip3 install flask
依赖wsgi(web服务网关接口) Werkzeug
from werkzeug.serving import sun_simple
def func(environ, start_response):
pass
host = '127.0.0.1'
port = 5000
if __name__=='__main__':
run_simple(host, port, func, **option) #host: 主机名,port: 端口
Hello, World
from flask import Flask
# app是实例化的Flask对象
app = Flask(__name__) # name是模块名
# url /index 会对应上函数index()
@app.route('/index')
def index()
return "Hello, world"
if __name__=='__main__':
app.run() # 执行了Flask类的run()方法
class Flask(App):
...
def run(
self,
host: str | None = None,
port: int | None = None,
debug: bool | None = None,
load_dotenv: bool = True,
**options: t.Any,
) -> None:
...
try:
# self即app对象
# 请求进来,会执行__call__()方法
run_simple(t.cast(str, host), port, self, **options)
# 这段代码是Flask框架中的一部分,它位于`app/run.py`文件中。
# 这段代码定义了一个名为`run_simple`的函数,它接受以下参数:
# - `host`: 主机名或IP地址,用于指定要运行Flask应用程序的服务器。
# - `port`: 端口号,用于指定要运行Flask应用程序的服务器上的端口。
# - `self`: Flask应用程序实例。
# - `**options`: 其他选项,如`use_reloader`、`use_debugger`、`use_evalex`等。
# `run_simple`函数的目的是在指定的服务器上运行Flask应用程序。
# 它首先使用`cast`函数将`host`参数转换为字符串类型,
# 然后使用`run_simple`函数在指定的服务器上运行Flask应用程序。
# `run_simple`函数的实现依赖于`werkzeug.serving.run_simple`函数。
# 它使用`werkzeug.serving.run_simple`函数在指定的服务器上运行Flask应用程序,
# 并处理各种选项,如自动重新加载、调试等。
...
def __call__(self, environ: dict, start_response: t.Callable) -> t.Any:
return self.wsgi_app(environ, start_response)
# 这段代码是Flask框架中`Flask`类的一个方法`__call__`的实现。
# 它是Flask应用程序的核心方法,当Flask应用程序被作为WSGI应用程序调用时,它会执行这个方法。
# `__call__`方法接收两个参数:`environ`和`start_response`。
# `environ`是一个字典,包含当前请求的所有环境变量,例如请求方法(GET、POST等)、请求路径、请求头等信息。
# `start_response`是一个可调用对象,它用于设置响应的状态码、响应头和响应缓冲区。
# `__call__`方法的主要目的是处理请求,并将处理结果返回给WSGI服务器。
# 它首先调用`self.wsgi_app`方法,该方法是Flask应用程序的WSGI应用程序,它将处理请求并返回响应。
# 然后,它将响应结果和`start_response`参数传递给`start_response`方法,
# 以便WSGI服务器可以将响应发送给客户端。
# 总之,`__call__`方法是Flask应用程序的核心功能,它处理请求、调用WSGI应用程序并返回响应,
# 从而使Flask应用程序成为了一个完整的WSGI应用程序。
本质是由werkzeug来实现的。
总结:
- Flask框架是基于werkzeug的wsgi实现的,Flask自己没有wsgi。
- 用户请求一旦到来,就会执行
app.__call__()方法。 - 写Flask的标准流程:创建Flask对象,匹配路由和视图函数,app.run
实现一个XX管理系统
用户登录&用户管理
from flask import Flask, render_template, \
jsonify, redirect, url_for, request # 导入的request就是请求
app = Flask(__name__)
DATA_DICT = {
1: {'name': '张三', 'age': 18},
2: {'name': '李四', 'age': 20},
}
@app.route('/login', methods=['GET', 'POST']) # 支持GET和POST请求
def login():
if request.method == 'GET':
# return 登录 类似HttpResponse
# return jsonify({'code': 0, 'msg': '登录成功'}) 返回JSON格式响应
return render_template('login.html') # 默认是从templates文件夹找
user = request.form.get('user')
pwd = request.form.get('pwd')
if user == 'admin' and pwd == '123456': # 假设登录成功了吧
return redirect('/index')
return render_template('login.html', msg='用户名或密码错误') # 登录失败,返回登录页面,并提示错误信息
@app.route('/index', endpoint='idx') # 通过endpoint给路由命名
def index():
data_dict = DATA_DICT
return render_template('index.html', data_dict=data_dict) # 登陆成功,返回首页
@app.route('/edit', methods=['GET', 'POST'])
def edit():
if request.method == 'GET':
nid = request.args.get('nid') # 用request.args取数据
nid = int(nid)
info = DATA_DICT[nid]
return render_template('edit.html', info=info) # 到edit.html页面进行修改
user = request.form.get('user')
age = request.form.get('age')
nid = request.args.get('nid') # 获取url上的参数
nid = int(nid)
DATA_DICT[nid]["user"] = user
DATA_DICT[nid]["age"] = age
return redirect(url_for("idx")) # 修改之后跳回首页
@app.route('/delete/<int:nid>', methods=['POST'])
def delete(nid):
del DATA_DICT[nid]
#return redirect('/index') 删除数据之后跳转回首页
return redirect(url_for("idx")) # 使用别名访问/index
if __name__ == '__main__':
app.run()
总结:
- Flask路由是用装饰器写的
- 路由参数有url, methods和endpoint。methods的默认值为
['GET', ], endpoint的默认值为函数名,且endpoint不能重名。 - 支持动态路由:
@app.route('/index/<int:nid>') - 获取提交的数据:GET方法
request.args, POST方法request.form - 返回数据:
render_template('模板文件'),jsonify({}),redirect(url)
保存用户的会话信息
from flask import session
app = Flask(__name__)
app.secret_key = "hrteMN9gnMwplaB2" # 随机字符串, 用于加密session
@app.route('/login', methods=['GET', 'POST'])
def login():
...
if user == 'admin' and pwd == '123456': # 假设登录成功了吧
session['user'] = "admin" # session是保存用户登录状态的,Flask框架下保存于用户的浏览器中
# 之后请求将session传入后被解密
return redirect('/index')
...
@app.route('/index', endpoint='idx')
def index():
username = session.get('user') # 取到解密后的session
if not username:
return redirect('/login') # 如果session无值,则重新登录
...
...
装饰器实现用户认证
import functools
...
def auth(func):
@functools.wraps(func)
def inner(*args, **kwargs):
username = session.get('user') # 取到解密后的session
if not username:
return redirect('/login') # 如果session无值,则重新登录
return func(*args, **kwargs)
return inner
...
@app.route('/index', endpoint='idx')
@auth
def index():
data_dict = DATA_DICT
return render_template('index.html', data_dict=data_dict) # 登陆成功,返回首页