今日内容概要
- flask和其他python web框架介绍
- flask快速使用
- 登陆 显示用户信息小案例
- 配置文件方式
- 路由系统
今日内容概要
flask和其他python web框架介绍
python web框架的本质都一样
1.同步框架
django 大而全 内置的app多 第三方app也多
flask 小而精 没有过多的内置组件 值完成web框架最基本的功能 需要借助于第三方来完成更加丰富的功能
web.py 是一个小巧灵活的python框架 它简单且功能强大 但国内很少使用
2.异步框架
fastapi python的异步web框架 不少公司在使用 https://fastapi.tiangolo.com/zh/
sanic Python的异步web框架 供支持异步高并发请求的web服务
tornado 异步框架 用到比较少了
同步框架和异步框架的区别
同步框架的意思:一个线程只处理一个请求
异步框架的意思:一个线程可以处理多个请求
异步框架可以很显著的提高并发量
django在3.x后就支持异步了 所以即是同步框架也是异步框架
flask介绍
flask是一个基于python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架
jinja2 模板语法 和django的dtl非常的像 但是比它强大
Werkzeug WSGI 符合wsgi协议的web服务器 django中使用的wsgiref
小案例:wsgiref写web
from wsgiref.simple_server import make_server
# mya 就等同于django
def mya(environ, start_response):
#把environ包装成了request
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] # 做成了response
if __name__ == '__main__':
myserver = make_server('', 8008, mya)
print('监听8010')
myserver.serve_forever()
使用werkzeug写web
from werkzeug.wrappers import Request, Response
@Request.application
def hello(request):
return Response('hello word')
if __name__ == '__main__':
from werkzeug.serving import run_simple
run_simple('localhost', 4000, hello)
flask快速使用
安装:pip install flask
安装最新的就行 2.x相比1.x虽然源代码动了 但是没有区别
from flask import Flask
# 实例化得到对象 传入一个任意字符串
app = Flask(__name__)
# 通过装饰器注册路由
@app.route('/')
def home():
return 'hello word'
if __name__ == '__main__':
# 启动 不传参数默认127.0.0.1 5000端口
app.run()
登陆 显示用户小案例
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post">
<p>用户名:<input type="text" name="username"></p>
<p>密码:<input type="password" name="password"></p>
<p><input type="submit" value="登陆"></p>{{error}}
</form>
</body>
</html>
home.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>
detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>名字是:{{user.name}}</p>
<p>年龄是:{{user['age']}}</p>
<p>性别是:{{user.get('gender')}}</p>
<p>{{user.text}}</p>
</body>
</html>
from flask import Flask, render_template, request, session, redirect, jsonify
# 实例化得到对象 传入一个任意字符串
app = Flask(__name__)
app.debug = True
app.secret_key = 'woefosngajsoidfjajwenfa'
USERS = {
1:{'name':'张三','age':18,'gender':'男','text':"道路千万条"},
2:{'name':'李四','age':28,'gender':'男','text':"安全第一条"},
3:{'name':'王五','age':18,'gender':'女','text':"行车不规范"},
}
# 通过装饰器注册路由
@app.route('/home')
def home():
if not session.get('user'):
return redirect('/login')
return render_template('home.html', user_dict=USERS)
# 添加转换器 可以接受参数
@app.route('/detail/<int:pk>')
# 路由中转换器名是啥就接收啥
def detail(pk):
# session中没有user说明没登陆 直接跳转到登陆界面
if not session.get('user'):
return redirect('/login')
user = USERS.get(pk)
return render_template('detail.html', user=user)
# 既可以通过传methods参数可以指定接受哪些请求
@app.route('/login', methods=['get', 'post'])
def login():
# request对象需要导入 post请求再进行逻辑判断
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
if username == 'lzj' and password == '123':
# 验证通过 存入session中 是模块 需要导入
session['user'] = username
return redirect('/home')
# 前后端混合 可以直接以位置参数的形式将页面需要的参数传递给页面
return render_template('login.html', error='用户名或密码错误')
return render_template('login.html')
@app.route('/test')
def test():
# 返回json格式 只能传字典和列表
return jsonify([{'name':'lzj','age':19}])
if __name__ == '__main__':
# 启动
app.run()
'''
总结
1.注册路由
app.route(路径,methods=[请求方式1,请求方式2])
2.新手四件套
render_template 返回页面 并且可以传值 和django有区别
redirect 重定向
return 字符串 直接返回字符串
jsonify 返回json格式
3.请求的request对象 是全局的 导入使用即可 但是在不同视图函数中并不会混乱 都是自己的
request.from 请求体中的内容转换成字典放在这
request.method 请求方式
4.session是全局的 也是导入使用即可 一定要指定秘钥
app.secret_key = '秘钥串'
session[''] = '' 放值
session.get() 取值
5.模板的渲染
兼容django的dtl语法 但更强大 可以加括号 字典也可以通过.values() .items()取值
6.转换器
@app.route('/路由/<int:pk>')
'''
配置文件方式
方式一:
app.debug = True # 调试模式 提示的信息更加详细 修改代码不需要重启 会自动重启
app.secret_key = '' # 给session设置秘钥
该方式只能设置debug和secret_key
方式二:
app.config['DEBUG'] = True
app.config['SECRET_KEY'] = ''
通过app.config设置 是一个字典 key值必须是大写
方式三:
app.config.from_pyfile('settings.py')
通过引入设置文件 并且变量名都为大写 不常用
方式四:
class BASE(object):
DEBUG = False
class ProductionConfig(BASE):
DATABASE_URI = 'mysql://user@localhost/foo'
class DevelopmentConfig(BASE):
DEBUG = True
DATABASE_URI = 'localhost'
app.config.from_object('DevalopmentConfig')
app.config.from_object('DevalopmentConfig')
通过引入类的方式 常用它 无需使用多个py文件管理多套配置
方式五:
app.config.from_envvar('环境变量名')
通过环境变量配置
方式六:
app.config.from_json('json文件名称')
必须是要是json格式 因为内部会执行json.loads
方式七:
app.config.from_mapping({'DEBUG':True})
通过字典的形式
路由系统
django中配置路由是在urls.py中来实现
flask是基于装饰器的 大部分都是通过装饰器来实现 也可以少部分抽取到py文件中
路由装饰器源码分析
@app.route('/login')
def login():
pass
本质上就是 index = app.route('/login')(index)
查看route函数
@setupmethod # 没见过 先不关注 rule就是传进来的/login options是多余的参数
def route(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: # rule:str 表示该参数接收字符串类型 ->表示返回的类型 其他同理
# f就是被装饰的函数 也就是login函数
def decorator(f: T_route) -> T_route:
# endpoint我们并没有传 也就是None 先忽略
endpoint = options.pop("endpoint", None)
# 真正的添加路由函数 查看源码发现self就是app对象
self.add_url_rule(rule, endpoint, f, **options)
return f
return decorator
查看源码发现真正添加路由的是add_url_rule函数 那么我们也可以手动添加
def home():
pass
app.add_url_rule('/', endpoint=None, view_func=home, methods=['GET'])
和django的添加路由有点相似
add_url_rule中的参数
rule url规则
view_func 视图函数名
defaults=None 默认值 当url中不需要参数 但是函数需要时可以使用 defaults={k:v}
endpoint=None 路由的别名 用于反向解析url
methods=Node 允许请求的方式 如['GET','POST']
strict_slashes=None 对url中最后的'/'是否严格要求
redirect_to=None 重定向到指定的地址
转换器
'default': UnicodeConverter,
'string': UnicodeConverter,
'any': AnyConverter,
'path': PathConverter,
'int': IntegerConverter,
'float': FloatConverter,
'uuid': UUIDConverter,
标签:__,return,name,框架,Flask,app,login,route
From: https://www.cnblogs.com/lzjjjj/p/17277467.html