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パラメーターを使用するルートと、URLパラメーターを使用しないルートの2つのルートがあります。

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パラメーターの値として使用されていることです。これはエラーを引き起こさないため、をヒットしたときに which がルーティングされ、キーワード引数として渡され、見たエラーが発生しrequire_post_dataます。decorator/<int>contact_id

于 2013-09-04T05:49:19.973 に答える