在传播到更具体的approutes之前处理烧瓶中的事件

时间:2014-03-13 22:27:49

标签: python python-2.7 flask

我有一个烧瓶应用程序。偶尔会遇到一系列类似的路线,这些路线非常相关(代码未经过测试,只是为了证明一点):

@app.route('/stats/charts/count/<attribute>', methods=['GET'])
def count_attribute(attribute):
  counter = collections.Counter()
  for x in csv_mod.data:
    counter[attribute] += 1
  return counter

@app.route('/stats/charts/filter/<attribute>/<value>', methods=['GET'])
def filter_attribute(attribute, value):
  filtered = []
  for entry in csv_mod.data:
    if getattr(entry, attribute) != value:
      filtered.append(entry)
  return filtered

现在让我们说他们也可以输入一个分割数据的查询参数。例如,他们将03放入请求中。在访问任何/stats/charts应用程序路线之前,我想要一个&#34;看门人&#34;在执行approute之前剪切此数据的方法,而没有明确声明在/stats/charts/

下的每个方法中运行此方法
@app.route('/stats/charts/*', methods=['GET']) # any route with this base
def cut_data():
  month = request.args.get('month', None)
  if month is None: 
    #propagate to the specific approute
  else:
    # cut data and then go to the specific approute

现在,如果他们在请求中访问带有:site:/stats/charts/count/crows/的{​​{1}},就会知道在继续执行&#34;实际&#34;之前正确地删除了数据。 approute。是否有办法在一系列方法中添加类似的通用方法?什么是最好的方式?

1 个答案:

答案 0 :(得分:2)

你可以把它变成装饰者;视图只是函数,装饰器可以为函数添加其他参数:

from functools import wraps

def cut_data(func):
    @wraps(func)
    def wrapper(*args, **kw):
        month = request.args.get('month', None)
        if month is None:
            # redirect to same endpoint with new query parameter
            return redirect(request.endpoint, month='some month', **request.view_args)

        # cut data
        data = some_magic(csv_mod.data, month)
        # call actual view function
        return func(data=data, *args, **kw)

    return wrapper

然后使用您的路线:

@app.route('/stats/charts/count/<attribute>', methods=['GET'])
@cut_data
def count_attribute(attribute, data=None):
    counter = collections.Counter()
    for x in data:
        counter[attribute] += 1
    return counter

@app.route('/stats/charts/filter/<attribute>/<value>', methods=['GET'])
@cut_data
def filter_attribute(attribute, value, data=None):
    filtered = []
    for entry in data:
        if getattr(entry, attribute) != value:
            filtered.append(entry)
    return filtered

并且Flask会调用包装器,并且可以使用额外的关键字参数data调用实际的视图函数,并为该月预先剪切数据。