简体   繁体   English

将Flask路由参数传递给装饰器

[英]Pass Flask route parameters into a decorator

I have written a decorator that attempts to check we have post data for a Flask POST route: 我写了一个装饰器,试图检查我们是否有Flask POST路线的发布数据:

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: 我有两条路线,一个是URL参数,另一条没有:

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: 当我运行一个命中update_contact的测试时,我得到以下异常:

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

But it looks like create_contact is working as expected. 但看起来create_contact正如预期的那样工作。

Why is contact_id being passed into decorator() ? 为什么将contact_id传递给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. 我相信你只是缺少一件事,就是实际调用require_post_data来生成update_contact路由中的装饰器函数。 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 . 详细解释是,您期望发生的事情(以及create contact发生的事情)是由require_post_data 生成decorator正在修改视图函数。 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. 在上面的update_contact ,实际发生的是view函数被传递给require_post_data 本身,并且只是用作required_fields参数的值。 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. 这不会导致错误,因此require_post_data愉快地返回decorator ,然后在您按/<int>时将其路由到,导致它作为关键字参数传递给contact_id ,从而导致您看到的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM