Django | Flask |
---|---|
Admin - Model | 原生无 |
Model | 原生无 |
Form | 原生无 |
session | 有-颠覆认知(存储到服务端内存中,浏览器的cookies中) |
教科书式框架 | 第三方组件非常丰富。一切从简 |
优势对比 | |
组件、功能全,教科书 | 轻,快 |
劣势对比 | |
占用资源,cpu,ram | 先天不足,第三方组件稳定性较差 |
创建项目复杂度高 |
from flask import Flask
# 命名
app = Flask('app.py')
# 或 app = Flask(__name__)
app.config['DEBUG'] = True
# 或 app.debug = True
@app.route('/')
def home():
return 'AH, you are visiting Flask-site!'
if __name__ == '__main__':
# 监听地址和端口,默认是127.0.0.1:5000
app.run('0.0.0.0', 5000)
# werkzeug调用run_simple
# wsgi处理请求头(网关接口)
# wsgi处理后的数据,environment。
@app.route('/index')
def index():
return 'hello world i am Flask'
@app.route('/index')
def index():
return render_template('index.html')
@app.route('/login')
def login():
return render_template('/index')
text/html
text/plain
,保留当前文件格式image/jepg
或者 image/png
audio/mpeg:<video> ,应该是<audio>
,chrome完成video/mp4:<video>
标签application/x-msdownload:xx.exe
from flask import send_file
@app.route('/get_file')
def get_file():
# 返回文件内容,自动识别文件类型
return send_file('app.py')
@app.route('/get_json')
def get_json():
d = {'k':'v'}
return jsonify(d)
# 请求方式和数据 5
1. request.method # 获取请求的方式
2. request.form # 获取 FormData 中数据(ajax)
.to_dict() # request.from.to_dict():返回对应的字典
# 类型:ImmutableMultiDict([])
3. request.args # 获取url中的参数
4. reqeust.values # 获取 url 和 FormData 中的数据,如果key相同 url中的会覆盖 form中数据
# CombinedMultiDict([ImmutableMultiDict([('id', '1')]), ImmutableMultiDict([])])
5. request.files # 获取 Form 中文件,返回 FileStroage中有 save() 方法和 filename属性
.save(文件路径)
.filename
# 请求来源相关 3
6. request.host # ip + port
7. request.path # url路由地址
8. request.url # 完整路径,如:http://127.0.0.1:5000/detail?id=2
# cookies相关 1
9. request.cookies # 字典,获取浏览器请求时带上的cookies
# 特殊数据封装 3
10.request.data # Content-type 中不包含 Form 或 FormData,保留请求体中的原始数据,b""类型
11.request.json # 请求头的 Content-type:application/json
# 请求体中的数据被序列化到request.json中,以字典的形式存放
from flask import Flask
app = Flask(__name__)
@app.route('/login', methods=['GET','POST',])
def login():
# 优先判断请求方式
# 如果是GET请求
if request.method == 'GET':
return render_template('login.html')
# 如果是POST请求,获取 用户名,密码 校验
else: # 405 请求方式不被允许
# request.form.to_dict()
my_file = request.files.get('my_file')
filename = my_file.filename
filepath = os.path.join('avatar', filename)
my_file.save(filepath)
if request.form.get('username') == 'xxx':
return 'Login OK!'
return '200 ok'
if __name__ == '__main__':
app.run()
app.config['DEBUG'] = True
或 app.debug = True
@app.route('/')
def stu():
return render_template('stu.html', stu=STUDENT,)
app.run('0.0.0.0:9527')
@app.template_global()
def ab(a,b):
return a+b
@app.route('/a')
def homea():
return render_template('a.html', ab=ab)
{% macro my_input(na, ty) %}
<input type="{{ ty }}" name="{{ na }}">
{% endmacro %}
{{ my_input('username', 'text') }}
from markupsafe import Markup
@app.route('/a')
def homea():
inp = Markup("<input type='submit' value='xxx'>")
return render_template('a.html', btn=inp)
def my_input(na, ty):
s = f"<input type='{ty}' value='{na}'>"
return Markup(s)
{{ btn | safe }}
{{ my_input('username', 'text') }}
from flask import session
# 密钥不能为空
app.secret_key = "1!@#$8943:''.,xvzn;5lk12@!lg)*743%^&"
# 装饰器
def warpper(func):
def inner(*args, **kwargs):
# 校验登录状态、校验session中有没有 user key
if session.get('user'):
return func()
else: # 校验失败,跳转到登录页面
return redirect('/login')
return inner
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
else:
if request.form.get('username') == 'henry':
return 'Login OK!'
else:
return 'failed'
@app.route('/')
@warpper
def homea():
return render_template('a.html')
__name__
,functools.wraps,在装饰器的inner上添加functors.wraps(func)
@app.route('/a', endpoint='end_a')
@warpper
def a():
pass
@app.route('/b', endpoint='end_b')
@warpper
def b():
pass
@app.route('/', endpoint='home')
@warpper
def home():
pass
@app.route(rule, methods=['get', 'POST', 'options'])
@app.route('/', endpoint=None)
def home():
return 'ok!'
from flask import Flask
url_for('end_a')
url_for('home')
# {'end_a':'/a', 'home': '/'}
@app.route(rule, endpoint=None, defaults={'count':20})
def home(count):
count = request.args.get('count', count)
return f'200 ok!{count}'
@app.route(rule, endpoint=None, strict_slashes=True)
def home():
return f'200 ok!{count}'
@app.route(rule, endpoint=None, redirect_to='/')
/home/<filename>
, /home/<int:page>
, /home/<ty>_<page>_<id>
,分页、获取文件、解决分类,解决正则路由@app.route('/home/<int:page>', endpoint='home',)
def home(page):
print(type(page))
return '200 ok!'
@app.route('/home/<page>_<ty>_...', endpoint='home',)
def home(page, ty, ...):
pass
@app.route('/home/<filename>', endpoint='home',)
def home(filename):
return send_file(f'media/{filename}')
app = Flask(__name__, template_folder='templates')
app = Flask(__name__, static_folder='img', static_url_path='/static')
# http://127.0.0.1:5000/static/1.jpeg
/staic_folder
http://127.0.0.1:5000/
<img src='访问地址'>
<img src='static/1.jpg'>
# 开启 debug 模式,自动重启、透传错误信息、log级别较低 debug 级别
app.debug = True
# 使用session
app.secret_key = 'R&w34hr*&%^R7ysdjh9qw78r^*&A%863'
# session名称
app.session_cookie_name = 'ah'
# session生命周期,20s过期为 None
app.permanent_session_lifetime = 20
# respone头中content-type:xxx
app.config['JSONIFY_MIMETYPE']='xxx'
import hashlib
class DubugConfig(object):
DEBUG = True
SECRET_KEY = '#$%^&fguyhij&^$EHBksdj`109u23'
PERMANENT_SESSION_LIFETIME = 3600
SESSION_COOKIE_NAME = 'ah'
class TestConfig(object):
TESTING = True
SECRET_KEY = hashlib.md5(f'{time.time()}#$%^&124:"hfag(&sfdgh3ir;dfguyhij&^$EHBksdj`109u23{time.time()}'.encode('utf-8')).hexdigest()
PERMANENT_SESSION_LIFETIME = 360000
SESSION_COOKIE_NAME = '$%^&124:"hfag('
from settings.py import DubugConfig,TestConfig
app.config.from_object(DubugConfig)
app.config.from_object(TestConfig)
from flask import Blueprint
# 蓝图标识必须唯一
bp = Blueprint('app01', __name__,url_prefix='/car')
or
bp = Blueprint(__name__, __name__,url_prefix='/car')
@bp.route('/user')
def user():
return 'I am app01!'
# 或 bp.add_url_rule()
# 访问当前蓝图中的装饰器
@bp.before_request
@bp.after_request
@bp.errorhandler(Http错误码)
from app01 import bp
app.register_blueprint(bp)
@app.before_reqeust
def be1():
print('i am be1')
@app.before_reqeust
def be2():
print('i am be2')
@app.after_request
def af1(res):
print('i am in af1')
return res
@app.after_request
def af2(res):
print('i am in af2')
return res
@app.errorhandler(404)
def error404(error_message):
print(error_message)
return 'xxx' # 5种类型
# CBV
from flask import views
app.add_url_rule('/login', view_func = Login.as_view(name='login_login'))
@app.before_request
def is_login():
return 1
@app.after_request
def login_ok(res):
return res
# methods:默认是类对应的方法
class Login(views.MethodView):
# decorators = []
def get(self):
return 'here is get.'
def post(self):
pass
def add_url_rule(self, rule, endpoint=None, view_func=None, **options):pass
# self:flask对象
# rule:路由
# endpoint=None,地址反解析使用,如果为None,则使用view_func的name
# view_func,视图函数,视图类.as_view(name='xxx')
def as_view(cls, name, *class_args, **class_kwargs):pass
# cls:视图类
# name:视图函数名
from flask import views
class Index(views.MethodView):
def get(self, *args, **kwargs):
pass
...
app.add_url_rule('/index', endpoint=None, view_func=Login.as_vxwiews(name='login')
# win
下载redis到指定目录,配置PATH即可
# mac
brew install redis
# 终端
redis-cli
# 总共 16 个库,0-15,用来数据隔离
select 8 # 切换 8 号库,默认 0 号库
set key value # 设置一个健值对,哈希存储结构{key:value}
keys pattern # 查询当前数据库中所有的key,如keys * 查询当前数据库中所有key
a* # 查询以 a开头
*n* # 包含 n
...
get key # 查询 key 对应的 value
from redis import Redis
redis_cli = Redis(host='127.0.0.1', port=6379, db=6)
redis_cli.set('name', 'echo')
from flask import Flask, request, session
from flask_session import Session
app = Flask(__name__)
# app.secret_key = '%^&*JBHJ%$*lkdsj'
# 使用 flask_session并使用 redis 存储session
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = Redis('127.0.0.1', 6379, db=10)
Session(app)
@app.route('/sets')
def sets():
session['key'] = 'henry'
return 'set ok!'
@app.route('/gets')
def gets():
return session.get('key')
if __name__ == '__main__':
app.run()
app.session_interface
# session_interface = self._get_interface(app)
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = Redis(host='192.168.12.9', 6379, db=10)
# redis通过pickle序列化,secret_key只有原生的config需要
# flask中的 requst 和 session
from functools import partial
def ab(a, b):
return a+b
new_func = partial(ab, 1, 3)
print(new_func())
import time
# local:{线程号1:{变量名:值},...}
from threading import local
class Foo(local):
num = 0
foo = Foo()
def addi(i):
foo.num = i
time.sleep(0.2) # 相当于 i/o 操作
print(foo.num)
from threading import Thread
for i in range(20):
th = Thread(target=addi, args=(i,))
th.strat()
# werkzeug 搭建app
from werkzeug.wrappers import Response, Request
from werkzeug.serving import run_simple
@Request.application
def app(req):
print(req, req.method)
return Response('200 ok')
run_simple('0.0.0.0', 5000, app)
# environ:wsgi 处理requset后的结果,请求原始信息
# 对象相当于dict
__slots__ = ('__stroage__', '__ident_func__')
原文:https://www.cnblogs.com/henryw/p/11574621.html