1 flask 介绍
| |
| -Django:大而全,快速开发,公司内部项目 |
| -Flask:小而精,不具备web开发好多功能,丰富的第三方插件 |
| -FastApi:异步框架,主要为了做前后端分离接口 |
| -Sanic:异步框架,只支持python3.6 及以上,性能比较高 |
| -Tornado:公司用的比较少。。。 |
| |
| |
| -pip3 install flask |
| |
fastapi
| import time |
| from fastapi import FastAPI |
| app = FastAPI() |
| @app.get('/') |
| async def index(): |
| time.sleep(3) |
| return {'code': 100, 'msg': '成功'} |
| |
| @app.get('/home') |
| async def home(): |
| time.sleep(2) |
| return {'code': 100, 'msg': 'home'} |
| |
| @app.get('/order') |
| async def home(): |
| time.sleep(2) |
| return {'code': 100, 'msg': 'order'} |
| |
| |
flask
| from flask import Flask |
| app = Flask(__name__) |
| @app.route('/', methods=['GET']) |
| def index(): |
| return 'hello world' |
| if __name__ == '__main__': |
| app.run() |
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('index.html','rb') as f: |
| data=f.read() |
| |
| elif environ.get('PATH_INFO') == '/login': |
| with open('login.html', 'rb') as f: |
| data = f.read() |
| else: |
| data=b'<h1>Hello, web!</h1>' |
| return [data] |
| |
| if __name__ == '__main__': |
| myserver = make_server('', 8011, mya) |
| print('监听8010') |
| myserver.serve_forever() |
| |
| |
| |

Werkzeug
| Werkzeug是一个WSGI工具包(在它基础上,继续封装),他可以作为一个Web框架的底层库。这里稍微说一下, werkzeug 不是一个web服务器,也不是一个web框架,而是一个工具包,官方的介绍说是一个 WSGI 工具包,它可以作为一个 Web 框架的底层库,因为它封装好了很多 Web 框架的东西,例如 Request,Response 等等 |
| |
| 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', 4000, hello) |

2 显示用户小案例
| from flask import Flask, render_template, request, redirect, session |
| |
| app = Flask(__name__, template_folder='templates') |
| 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('/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 == 'lqz' and password == '123': |
| |
| session['username'] = username |
| |
| return redirect('/index') |
| else: |
| return render_template('login.html', error='用户名或密码错误') |
| |
| |
| @app.route('/index') |
| def index(): |
| |
| if session.get('username'): |
| return render_template('index.html',users=USERS) |
| else: |
| return redirect('/login') |
| |
| |
| |
| @app.route('/detail/<int:pk>') |
| def detail(pk): |
| user=USERS.get(pk) |
| return render_template('detail.html',user=user) |
| |
| if __name__ == '__main__': |
| app.run() |
| |
| |
| |
| ''' |
| 1 新手三件套: 1 直接返回字符串 2 render_template 3 redirect |
| 2 flask的路由写法,是基于装饰器的 @app.route('/detail/<int:pk>' ,methods=['GET']) |
| 3 路由转换器跟django一样 |
| 4 取出前端post请求提交的数据:request.form |
| 5 取出请求方式:request.method |
| 6 使用session设置值和取值 |
| -session[key]=value |
| -session.get('key') |
| 7 flask的模板语法完全兼容dtl,并且它更强大,可以加括号执行 |
| |
| ''' |
detail.html
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>Title</title> |
| |
| </head> |
| <body> |
| <h1>详细信息 {{user.name}}</h1> |
| <div> |
| {{user.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 users.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> |
| <form action="" method="post"> |
| <p>用户名:<input type="text" name="username"></p> |
| <p>密码:<input type="password" name="password"></p> |
| <p><input type="submit" value="提交">{{error}}</p> |
| |
| </form> |
| |
| |
| </body> |
| </html> |
3.登录认证装饰器
| |
| - |
| |
| |
| -如果不指定endpoint,反向解析的名字都是函数名,不加装饰器没有问题,就是正常函数index,detail |
| -如果加了装饰器---》index,detail都变成了inner---》反向解析的名字都是函数名inner,报错了 |
| -wrapper装饰器----》把它包的更像---》函数名变成了原来函数的函数名 |
| |
| |
| |
| |
| def add(func): |
| print(func) |
| |
| |
| |
| |
| |
| |
| class Person: |
| def __call__(self, func): |
| def inner(*args, **kwargs): |
| |
| res = func(*args, **kwargs) |
| return res |
| return inner |
| |
| p = Person() |
| |
| |
| @p |
| def test(): |
| print("test") |
| |
| print(test) |
| |
| def auth(func): |
| def inner(*args, **kwargs): |
| res = func(*args, **kwargs) |
| res.name='lqz' |
| return res |
| return inner |
| |
| @auth |
| class Foo(): |
| pass |
| |
| f=Foo() |
| print(f) |
| print(f.name) |
| |
| |
| |
| |
| @auth(10) |
| class Foo(): |
| pass |
4、配置文件
| from flask import Flask, request, render_template, redirect, session,jsonify |
| |
| app = Flask(__name__) |
| # flask的所有配置都放在app中了,以后直接使用app对象,获取配置信息即可 |
| |
| # 设置的方式一:(测试用) |
| # app.debug=True |
| # app.secret_key='dasdfasdfasd' |
| |
| # |
| # app.config['DEBUG']=True |
| # app.config['SECRET_KEY']='sdfasdfasd' |
| # print(app.config) |
| |
| |
| # |
| # app.config.from_pyfile("settings.py") |
| # print(app.config) |
| |
| # |
| # app.config.from_object('settings.DevelopmentConfig') |
| # app.config.from_object('settings.ProductionConfig') |
| # print(app.config) |
| |
| # |
| #通过环境变量配置 |
| # app.config.from_envvar("环境变量名称") |
| |
| # json |
| # app.config.from_json("json文件名称") |
| # JSON文件名称,必须是json格式,因为内部会执行json.loads |
| |
| |
| # 字典格式---》配置中心 |
| # app.config.from_mapping({'DEBUG': True}) |
| |
| |
| @app.route('/login', methods=['GET', 'POST']) |
| def index(): |
| return 'hello web' |
| |
| if __name__ == '__main__': |
| app.run() |
| |
5 路由系统
5.1 路由本质
| |
| |
| |
| |
| |
| |
| |
| |
| @app.route('/login') |
| def index(): |
| pass |
| |
| |
| |
| |
| -rule是路径 |
| -其他参数都给了options |
| |
| |
| endpoint = options.pop("endpoint", None) |
| |
| |
| |
| self.add_url_rule(rule, endpoint, f, **options) |
| return f |
| |
| |
| 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 |
| |
| app.add_url_rule('/', endpoint=None, view_func=home, methods=['GET']) |
| |
| |
| |
| |
5.2 路由参数add_url_rule
| |
| |
| |
| |
| |
| |
| |
| |
| strict_slashes = None |
| ''' |
| @app.route('/index', strict_slashes=False) |
| #访问http://www.xx.com/index/ 或http://www.xx.com/index均可 |
| @app.route('/index', strict_slashes=True) |
| #仅访问http://www.xx.com/index |
| ''' |
| |
| |
| redirect_to = None, |
| ''' |
| @app.route('/index/<int:nid>', redirect_to='/home/<nid>') |
| ''' |
| |
| |
| |
| |
| |
| |
| |
| |
5.3 转换器
| 'default': UnicodeConverter, |
| 'string': UnicodeConverter, |
| 'any': AnyConverter, |
| 'path': PathConverter, |
| 'int': IntegerConverter, |
| 'float': FloatConverter, |
| 'uuid': UUIDConverter, |
| |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)