02 flask源码剖析之flask快速使用

02 flask快速使用

1.flask与django的区别

  1. django是个大而全的框架,flask是一个轻量级的框架。

  2. django内部为我们提供了非常多的组件:orm / session / cookie / admin / form / modelform / 路由 / 视图 / 模板 / 中间件 / 分页 / auth / contenttype / 缓存 / 信号 / 多数据库连接 ;

    flask框架本身没有太多的功能:路由/视图/模板(jinja2)/session/中间件 ,第三方组件非常齐全。

  3. django的请求处理是逐一封装和传递; flask的请求是利用上下文管理来实现的。

2. 安装

pip3 install flask

3. 依赖wsgi Werkzeug

from werkzeug.serving import run_simple

def func(environ, start_response):
    print('请求来了')
    pass

if __name__ == '__main__':
    run_simple('127.0.0.1', 5000, func)
from werkzeug.serving import run_simple

class Flask(object):
    
    def __call__(self,environ, start_response):
        return "xx"
app = Flask()

if __name__ == '__main__':
    run_simple('127.0.0.1', 5000, app)
from werkzeug.serving import run_simple

class Flask(object):
    
    def __call__(self,environ, start_response):
        return "xx"
    
    def run(self):
        run_simple('127.0.0.1', 5000, self)
        
app = Flask()

if __name__ == '__main__':
    app.run()

4. 快速使用flask

from flask import Flask

# 创建flask对象
app = Flask(__name__)

@app.route('/index')
def index():
    return 'hello world'


@app.route('/login')
def login():
    return 'login'

if __name__ == '__main__':
    app.run()

总结:

  • flask框架是基于werkzeug的wsgi实现,flask自己没有wsgi。
  • 用户请求一旦到来,就会执行 app.__call__ 方法 。
  • 写flask标准流程

5. 用户登录&用户管理

from flask import Flask, render_template, jsonify,request,redirect,url_for

app = Flask(__name__)

DATA_DICT = {
    1: {'name':'张三',"age":73},
    2: {'name':'李四',"age":84},
}

@app.route('/login',methods=['GET','POST'])
def login():
    if request.method == 'GET':
        # return '登录' # HttpResponse
        # return render_template('login.html') # render
        # return jsonify({'code':1000,'data':[1,2,3]}) # JsonResponse
        return render_template('login.html')
    user = request.form.get('user')
    pwd = request.form.get('pwd')
    if user == '张三' and pwd == "123":
        return redirect('/index')
    error = '用户名或密码错误'
    # return render_template('login.html',**{'error':error})
    return render_template('login.html',error=error)

@app.route('/index',endpoint='idx')
def index():
    data_dict = DATA_DICT
    return render_template('index.html',data_dict=data_dict)

@app.route('/edit',methods=['GET','POST'])
def edit():
    nid = request.args.get('nid')
    nid = int(nid)

    if request.method == "GET":
        info = DATA_DICT[nid]
        return render_template('edit.html',info=info)

    user = request.form.get('user')
    age = request.form.get('age')
    DATA_DICT[nid]['name'] = user
    DATA_DICT[nid]['age'] = age
    return redirect(url_for('idx'))

@app.route('/del/<int:nid>')
def delete(nid):
    del DATA_DICT[nid]
    # return redirect('/index')
    return redirect(url_for("idx"))

if __name__ == '__main__':
    app.run()

总结

  1. flask路由

    @app.route('/login',methods=['GET','POST'])
    def login():
    	pass
    
  2. 路由的参数

    @app.route('/login',methods=['GET','POST'],endpoint="login")
    def login():
    	pass
    	
    # 注意:endpoint不能重名
    
  3. 动态路由

    @app.route('/index')
    def login():
    	pass
    	
    @app.route('/index/<name>')
    def login(name):
    	pass
    	
    @app.route('/index/<int:nid>')
    def login(nid):
    	pass
    
  4. 获取提交的数据

    from flask import request
    
    @app.route('/index')
    def login():
    	request.args # GET形式传递的参数
    	request.form # POST形式提交的参数
    
  5. 返回数据

    @app.route('/index')
    def login():
    	return render_template('模板文件')
    	return jsonify()
    	reutrn redirect('/index/') # reutrn redirect(url_for('idx'))
    	return "...."
    
  6. 模板处理

    {{ x }}
    {% for item in list %}
    	{{item}}
    {% endfor %}
    
    

6.保存用户会话信息

  1. 代码示例

    import functools
    from flask import Flask, render_template, jsonify,request,redirect,url_for,session
    
    app = Flask(__name__)
    
    app.secret_key = 'uo3kj9sd78ij3l4kj9sd87fj'
    
    DATA_DICT = {
        1: {'name':'张三',"age":73},
        2: {'name':'李四',"age":84},
    }
    
    
    def auth(func):
        @functools.wraps(func)
        def inner(*args,**kwargs):
            username = session.get('xxx')
            if not username:
                return redirect(url_for('login'))
            return func(*args,**kwargs)
        return inner
    
    
    @app.route('/login',methods=['GET','POST'])
    def login():
        if request.method == 'GET':
            return render_template('login.html')
        user = request.form.get('user')
        pwd = request.form.get('pwd')
        if user == 'changxin' and pwd == "dsb":
            session['xxx'] = 'zhangsan'
            return redirect('/index')
        error = '用户名或密码错误'
        return render_template('login.html',error=error)
    
    @app.route('/index',endpoint='idx')
    @auth
    def index():
        data_dict = DATA_DICT
        return render_template('index.html',data_dict=data_dict)
    
  2. 保存用户会话信息总结

    • flask的session是放在用户的浏览器的,服务端不存储,是将用户的session值通过secret_key加密后返回给浏览器,存储在cookie中,下次请求过来时flask将该段密文进行解密
    • flask的session必须依赖secret_key
    • 如果用装饰器保留会话信息的话,必须要在装饰器加@functools.wraps,保留元数据,否则每个被装饰的函数都是相同的别名(endpoint),会报错
    • @auth装饰器放在@app.route的下边,请求过来应该先执行auth函数判断是否已经登录

7. 蓝图(blue print)

  1. 构建业务功能可拆分的目录结构。

    • pro_excel
      • pro_excel
        • static
        • templates
        • views
          • wy.py
          • my.py
        • __init__.py
      • manage.py
  2. 创建蓝图

    __init__.py

    from flask import Flask
    from .views.my import xmy
    from .views.wy import xwy
    
    def create_app():
        app = Flask(__name__)
        app.secret_key = 'asdfaskdfjsd'
    
        @app.route('/index')
        def index():
            return 'index'
    
        app.register_blueprint(xmy)
        app.register_blueprint(xwy)
    
        return app
    

    wy.py

    from flask import Blueprint
    
    xwy = Blueprint('wy', __name__)
    
    @xwy.route('/f3')
    def f1():
        return '我是wy'
    

    my.py

    from flask import Blueprint
    
    xmy = Blueprint('my',__name__)
    
    @xmy.route('/f1')
    def f1():
        return '我是my'
    

    manage.py

    from pro_excel import create_app
    
    app = create_app()
    
    if __name__ == '__main__':
        app.run()
    
    
    
  3. 蓝图总结

    • 创建蓝图的函数名create_app不能修改,flask第三方组件特别多,有利于以后用flask用第三方组件
    • flask中的蓝图和django中路由分发差不多
原文地址:https://www.cnblogs.com/liubing8/p/11930127.html