博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Flask 视图,中间件
阅读量:7073 次
发布时间:2019-06-28

本文共 5239 字,大约阅读时间需要 17 分钟。

视图

FBV

def index(nid):       """    请求相关信息        request.method      # 请求方式    request.args       # get 方式的参数获取     request.form      # post 方式的参数获取    request.values        request.cookies          request.headers    request.path      # 请求资源路径    request.full_path   # 请求全部资源漫画    request.script_root    request.url        # 全部请求路径 (带协议带域名)    request.files      # 请求文件    obj = request.files['the_file_name']    obj.save('/var/www/uploads/' + secure_filename(f.filename)) """     dic = {
"k1":"v1"}   """ 返回响应体的4种形式 字符串 jsonify 模板 跳转 url """   # return "index"   # return jsonify(dic)  # return render_template("xxx.html",dic=dic) # 可带数据传递  # return redirect(url_for("index")) # 跳转通过 url_for 反向解析       """ 定制响应头的时候构造响应体用到 make_response """
  # 如果想设置响应头和回显cookie,就需要用到make_response  # response = make_response(render_template('index.html'))  # response = make_response("字符串")  # response是flask.wrappers.Response类型  # response.delete_cookie('key')  # response.set_cookie('key', 'value')  # response.headers['X-Something'] = 'A value'  # return response
from flask import make_response,headers,set_cookie    obj = make_response(jsonify(dic))    obj.headers["xxxxx"] = "123"    obj.set_cookie("key","value")    return obj

装饰器实现中间件功能

预备处理视图函数初始状态

@app.route('/index')def index():    if not session.get('user'):        return redirect(url_for('login'))    return render_template('index.html',stu_dic=STUDENT_DICT)

视图级别加装,比较适用于对少量视图进行处理

import functoolsdef auth(func):    @functools.wraps(func)    def inner(*args,**kwargs):        if not session.get('user'):            return redirect(url_for('login'))        ret = func(*args,**kwargs)        return ret    return inner@app.route('/index')@authdef index():    return render_template('index.html',stu_dic=STUDENT_DICT)

全局级别加装

@app.before_requestdef xxxxxx():    if request.path == '/login':        return None    if session.get('user'):        return None    return redirect('/login')

除了 before_request 以外还有其他特殊装饰器:

1. before_request    谁先定义谁先执行    执行多个 before 的时候如果再中间有返回值,对于after 的执行直接执行最后一次定义的那个    2. after_request    谁后定义谁执行 3. before_first_request4. template_global5. template_filter6. errorhandler
from flask import Flaskapp = Flask(__name__)@app.before_requestdef x1():    print('before:x1')    return '滚'@app.before_requestdef xx1():    print('before:xx1')@app.after_requestdef x2(response):    print('after:x2')    return response@app.after_requestdef xx2(response):    print('after:xx2')    return response@app.route('/index')def index():    print('index')    return "Index"@app.route('/order')def order():    print('order')    return "order"if __name__ == '__main__':    app.run()
befor/after_request 示例
from flask import Flaskapp = Flask(__name__)@app.before_first_requestdef x1():    print('123123')@app.route('/index')def index():    print('index')    return "Index"@app.route('/order')def order():    print('order')    return "order"if __name__ == '__main__':    app.run()
before_first_request 示例
@app.errorhandler(404)def not_found(arg):    print(arg)    return "没找到"
errorhandler 示例

CBV

def auth(func):    def inner(*args, **kwargs):        result = func(*args, **kwargs)        return result    return inner# 继承自views.MethodView        采用CBV写法时,为了简单,都是采用继承MethodView的方式写的class IndexView(views.MethodView):    # methods = ['POST']  #只允许POST请求访问    decorators = [auth,]  #如果想给所有的get,post请求加装饰器,就可以这样来写,也可以单个指定    def get(self):   #如果是get请求需要执行的代码        v = url_for('index')        print(v)        return "GET"    def post(self):  #如果是post请求执行的代码        return "POST"app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))  #name指定的是别名,会当做endpoint使用

 

def auth(func):    def inner(*args, **kwargs):        print('before')        result = func(*args, **kwargs)        print('after')        return result    return inner# 也可以再往上继承自Viewclass IndexView(views.View):    methods = ['GET']    decorators = [auth, ]    # 如果继承自View,就需要dispatch_request    def dispatch_request(self):        print('Index')        return 'Index!'app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))  # name=endpoint

文件上传

客户端

  • 必须要在表单中上传
  • 提交方式必须是 post
  • enctype 属性必须是 multipart/form-data
上传文件:

服务端

文件会上传到缓存区, 通过 request.files 获取上传文件

拿到返回值可以调用 save , filename 方法

f = request.file['name'] # f.save('路径') # f.filename # 得到文件原始名称 f.save('static/' + f.filename) # 如果不存在 static 会报错

此方法在上传重名文件的时候会覆盖, 因此需要自己设定绝不会重名的方式,比如用时间戳

中间件

首先要知道我们利用请求扩展里提供的装饰器也能够做一些中间件的事,我们这里说的是根据flask的源码流程进行自定义方法来实现中间件的操作

具体流程:

app.run会执行werkzeug(第三方WSGI模块)中的run_simple方法,继而执行inner方法,继续执行make_server方法,

make_sever方法就会返回一个BaseWSGIServer对象,主要是起socket,

当有请求过来时就会触发flask的call方法,继而执行wsgi_app方法

利用app.run中的wsgi_app方法可以自定义类,定义的_ _call_ _方法里就可以做一些中间件的事

from flask import Flaskapp = Flask(__name__)@app.route('/')def index():    return 'Hello World!'class Md(object):    def __init__(self,old_wsgi_app):        self.old_wsgi_app = old_wsgi_app    def __call__(self,  environ, start_response):        print('开始之前')        ret = self.old_wsgi_app(environ, start_response)        print('结束之后')        return retif __name__ == '__main__':    app.wsgi_app = Md(app.wsgi_app)    app.run()

 

转载于:https://www.cnblogs.com/shijieli/p/10354407.html

你可能感兴趣的文章
linux安装软件备忘
查看>>
Springboot 笔记
查看>>
自己动手实现RPC服务调用框架
查看>>
AngularJs学习笔记--bootstrap
查看>>
String 、InputStream、Reader 的转换
查看>>
为Sublime Text 2安装Emmet(原Zen Coding)
查看>>
使用 IBM Data Studio 开发调试 DB2 存储过程
查看>>
Hyperledger Fabric 客户端开发二
查看>>
hibernate插入CLOB大数据类型
查看>>
4、ES5对Object对象的扩展。
查看>>
block的回调作用
查看>>
如何实现类似微信朋友圈的feed功能(第一版)
查看>>
安装NODEJS的三种方法
查看>>
如何让Mac完全读写NTFS格式分区
查看>>
百万级很快的分页联合
查看>>
手机内存卡修复工具软件大师免费试用版
查看>>
获取屏蔽符号<!-- -->屏蔽的字符串的代码
查看>>
struct和typedef struct
查看>>
Notification启动Activity, 恢复任务栈
查看>>
使用Python进行并发编程
查看>>