将Flask路径参数传递给装饰器 [英] Pass Flask route parameters into a decorator

查看:134
本文介绍了将Flask路径参数传递给装饰器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



这里是我的装饰器:



$ $ p $ $ $ c $ def def require_post_data(required_fields = None):
def decorator(f):
@wrap(f)
def decorated_function(* args,** kwargs):required_fields中required_field的

如果不是request.form.get(required_field,None):
return jsonify({error:Missing%s from发布数据。%
required_field}),400
else:
如果不是request.form:
返回jsonify({error:没有发布数据,正在中止。 }),400
return f(* args,** kwargs)
return decorated_function
return decorator

我有两条路线,一个URL参数,另一个没有:

  from瓶导入蓝图,jsonif y,请求

mod = Blueprint('contacts',__name__,url_prefix ='/ contacts')


@ mod.route('/',methods = ['POST'])
@require_post_data(['customer_id','some_other_required_field'])
def create_contact():
#做一些生意


@ mod.route('/< int:contact_id>',methods = ['POST'])
@require_post_data
def update_contact(contact_id):
#做一些生意

当我运行一个测试,命中 update_contact ,我得到以下异常:

pre $ TypeError:decorator()得到一个意想不到的关键字参数'contact_id'

但看起来像 create_contact 为什么将 contact_id 传递给 decorator()

解决方案

我相信你只是缺少一件事,实际上是调用 require_post_data update_contact 路由中产生装饰器函数。这应该解决它:

  @ mod.route('/< int:contact_id>',methods = ['POST' ])
@require_post_data()#< - 注意parens
def update_contact(contact_id):
#做一些生意

详细的解释是你期望发生的事情(以及 create contact 中发生的事情)是view函数正在由装饰器产生由 require_post_data 修改。在上面的 update_contact 中,实际发生的事情是view函数被传递给 require_post_data 本身,只是用作 required_fields 参数的值。这不会导致错误,所以 require_post_data 快乐地返回装饰器,然后按 /< int> ,导致它传递 contact_id 作为关键字参数,导致您看到的错误。

I have written a decorator that attempts to check we have post data for a Flask POST route:

Here's my decorator:

def require_post_data(required_fields=None):
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            for required_field in required_fields:
                if not request.form.get(required_field, None):
                    return jsonify({"error": "Missing %s from post data." %
                                    required_field}), 400
            else:
                if not request.form:
                    return jsonify({"error": "No post data, aborting."}), 400
            return f(*args, **kwargs)
        return decorated_function
    return decorator

And I have two routes, with with a URL param and the other without:

from flask import Blueprint, jsonify, request

mod = Blueprint('contacts', __name__, url_prefix='/contacts')


@mod.route('/', methods=['POST'])
@require_post_data(['customer_id', 'some_other_required_field'])
def create_contact():
    # Do some business


@mod.route('/<int:contact_id>', methods=['POST'])
@require_post_data
def update_contact(contact_id):
    # Do some business

When I run a test that hits update_contact, I'm getting the following exception:

TypeError: decorator() got an unexpected keyword argument 'contact_id'

But it looks like create_contact is working as expected.

Why is contact_id being passed into decorator()?

解决方案

I believe you're just missing one thing, which is to actually call require_post_data to produce a decorator function in the update_contact route. This should fix it:

@mod.route('/<int:contact_id>', methods=['POST'])
@require_post_data() # <- note the parens
def update_contact(contact_id):
    # Do some business

The detailed explanation is that what you expected to happen (and what is happening in create contact) is that the the view function is being modified by the decorator produced by require_post_data. In your update_contact above, what is actually happening is that the view function is being passed to require_post_data itself and simply used as the value of the required_fields parameter. This doesn't cause an error so require_post_data happily returns decorator which is then routed to when you hit /<int>, causing it to be passed contact_id as a keyword argument, resulting in the error you saw.

这篇关于将Flask路径参数传递给装饰器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆