在视图后执行的金字塔中添加函数

Add function in pyramid that executes after view

如何将代码添加到我的金字塔应用程序中,该应用程序在视图中的代码之后执行?

我需要在查看代码之前和之后对我的烧杯会话做一些事情。之前是没问题的,我用的是@subscriber(NewRequest)。到目前为止我尝试过的所有方法似乎都为时已晚(我写入会话的值似乎没有保存,尽管代码已执行,正如我在日志中看到的那样)。

我尝试将其放入 @subscriber(BeforeRender)@subscriber(NewResponse),并在完成的回调中添加 NewRequestevent.request.add_finished_callback(finished_callback) – None我写入会话的值的一部分。只有我在视图处理程序中添加为最后一行的那一行(但我不会在我的所有视图中都写那一行)。

pyramid docs on NewResponse状态:

Postprocessing a response is usually better handled in a WSGI middleware component than in subscriber code that is called by a pyramid.interfaces.INewResponse event. [...]

但是我对此迷路了,因为我不太了解 wsgi,并且试图通过 google 找到一个进入点并没有指向我的任何地方。

Tweens (be-tween) 允许您在每个请求前后执行代码。

我的解决方案是从@MikkoOhtamaa 的回答中得到的,但我希望代码在此页面上,所以我做了一些解释:

这可以通过补间来实现。这是一个函数(或其他可调用函数),它被调用而不是视图并获得调用视图的工作,因此您可以在调用之前和之后做一些事情。使用它我也摆脱了 @subscriber(NewRequest) 并将其全部放在一个地方。想象一下,在您的项目 main init.py 中创建 wsgi-app。该项目的名称将是 myapp.

def values_tween_factory(handler, registry):
    """
    Factory for creating the tween that wraps around the view.
    """
    def values_tween(request):
        """
        This is called in stead of the view with the view as param.
        """
        # do stuff before view code with request and session
        request.some_values = request.session.get('stored_values', [])
        # execute the view, creates the response
        response = handler(request)
        # do stuff after the view code with request and session
        request.session['stored_values'] = request.some_values
        # return the response returned by the view
        return response

    # return the new tween
    return state_tween

# [... other module level stuff ...]


def main(global_config, **settings):
    """
    The main function creating the wsgi-app.
    """
    config = Configurator(settings=settings)

    # [...] other stuff, like DB

    # register the tween - must be done by dotted name
    config.add_tween('myapp.values_tween_factory')

    # ... do more other stuff

    application = config.make_wsgi_app()
    # done - return created application object:
    return application