【问题标题】:Pass Flask route parameters into a decorator将 Flask 路由参数传递给装饰器
【发布时间】:2013-09-04 05:04:32
【问题描述】:

我编写了一个装饰器,它试图检查我们是否有 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()

【问题讨论】:

  • 旧帖子,但是您在哪里定义了要传递给 @require_post_data 装饰器的 required_fields 字典?
  • 错字 - 那应该是一个列表:@require_post_data(['customer_id', 'some_other_required_field'])

标签: python flask


【解决方案1】:

我相信您只是缺少一件事,即实际调用 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,然后在您点击/&lt;int&gt; 时将其路由到,从而将contact_id 作为关键字参数传递,从而导致您看到的错误。

【讨论】:

  • 没问题!这个问题对我来说真的很有趣,因为它说明了我认为 python 存在的一些问题。
  • @Chris 您实际上可以通过检查 required_fields 是否可调用来解决此问题:return decorator(required_fields) if callable(required_fields) else decorator 将允许您调用 @require_post_data 带或不带括号。
  • 有点不相关,但是你们知道有没有办法在脚本的其他部分使用传递给装饰器的变量?我需要使用传递给装饰器的变量来进行一些 mysql 查询。如何才能做到这一点?谢谢
猜你喜欢
  • 2016-02-14
  • 2014-11-17
  • 2017-12-13
  • 2021-11-21
  • 2018-08-24
  • 2014-10-01
  • 1970-01-01
  • 2022-07-12
  • 2017-12-13
相关资源
最近更新 更多