6

我编写了一个装饰器,试图检查我们是否有 Flask POST 路由的发布数据:

这是我的装饰器:

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

我有两条路线,有一个 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

当我运行命中的测试时update_contact,我收到以下异常:

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

但它看起来像create_contact预期的那样工作。

为什么contact_id被传入decorator()

4

1 回答 1

10

我相信您只是缺少一件事,那就是实际调用以在路由require_post_data中生成装饰器函数。update_contact这应该解决它:

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

详细的解释是,您期望发生的事情(以及在 中发生的事情create contact)是视图函数正在被decorator 生成的修改require_post_data。在你update_contact上面,实际发生的是视图函数被传递给require_post_data 它自己并简单地用作required_fields参数的值。这不会导致错误如此require_post_data愉快地返回decorator,然后在您点击时将其路由到/<int>,导致它contact_id作为关键字参数传递,从而导致您看到的错误。

于 2013-09-04T05:49:19.973 回答