在金字塔中呼叫另一个视图

2024-05-23 17:32:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我的目标:在金字塔中,调用另一个视图可调用,并在不知道视图可调用的任何细节的情况下获取Response对象。

在我的金字塔应用程序中,假设我有一个视图“foo”,它是使用view_config decorator定义的:

@view_config(route_name="foo",
             renderer="foo.jinja2")
def foo_view(request):
    return {"whereami" : "foo!"}

现在假设我想将“bar”路由到一个暂时执行相同操作的视图,因此它在内部调用foo_view,并返回其响应:

@view_config(route_name="bar")
def bar_view(request):
   return foo_view(request)

……但是等等!这不起作用,因为foo_view不返回Response,所以它的渲染器会返回。

所以,这将起作用:

@view_config(route_name="bar",
             renderer="foo.jinja2")
def bar_view(request):
    return foo_view(request)

因为它将应用与foo_view相同的渲染器。但是这是不好的,因为我现在必须通过复制renderer值来重复我自己,并且必须知道正在调用的视图的renderer。

因此,我希望在金字塔中有一些可用的函数,允许调用另一个可调用的视图并在不知道或不关心如何呈现的情况下获取Response对象:

@view_config(route_name="bar")
def bar_view(request):
    response = some_function_that_renders_a_view_callable(foo_view, request)
    return response

什么是some_function_that_renders_a_view_callable

pyramid.views.render_view似乎按名称搜索视图;我不想给出视图名称。

(注意:返回HTTPFound以使客户端重定向到目标路由是我试图避免的。我想“内部”重定向)。


Tags: 对象nameview视图config目标returnfoo
3条回答

可以使用^{}调用视图:

from wsgiref.simple_server import make_server

from pyramid.config import Configurator

from pyramid.request import Request


def view_one(request):

    subreq = Request.blank('/view_two')
    response = request.invoke_subrequest(subreq)
    return response

def view_two(request):

    request.response.body = 'This came from view_two'
    return request.response

if __name__ == '__main__':

    config = Configurator()
    config.add_route('one', '/view_one')
    config.add_route('two', '/view_two')
    config.add_view(view_one, route_name='one')
    config.add_view(view_two, route_name='two')
    app = config.make_wsgi_app()
    server = make_server('0.0.0.0', 8080, app)
    server.serve_forever()`

When /view_one is visted in a browser, the text printed in the browser pane will be "This came from view_two". The view_one view used the pyramid.request.Request.invoke_subrequest() API to obtain a response from another view (view_two) within the same application when it executed. It did so by constructing a new request that had a URL that it knew would match the view_two view registration, and passed that new request along to pyramid.request.Request.invoke_subrequest(). The view_two view callable was invoked, and it returned a response. The view_one view callable then simply returned the response it obtained from the view_two view callable.

我也在挣扎。我有一个使用render_to_response method的解决方案,尽管我确信有一个“更正确”的方法来实现它。不过,在有人发布之前,我是这样处理的:

from pyramid.renderers import render_to_response

@view_config(route_name="foo", renderer="foo.mak")
def foo_view(request):
    return {'stuff':'things', '_renderer':'foo.mak')

def bar_view(request):
    values = foo_view(request)
    renderer = values['_renderer']
    return render_to_response(renderer,values)

(金字塔1.3)

这需要使用呈现器,但是通过在原始视图的返回值中声明该呈现器,您可以在另一个视图中检索它,而不知道它是什么。我怀疑这样做的必要性是不容易找到的,因为有其他更好的方法来完成这个解决方案解决的任务。

另一个缺点是它依赖于可调用视图的直接导入。如果能直接按路线查找就好了。

是的。有一些担忧

  • 不返回响应
  • 谓词/呈现器
  • 权限
  • 与旧请求关联的请求属性

这就是为什么你不应该把视图作为函数调用,除非你知道你在做什么

金字塔创建者为服务器端重定向做了很棒的工具-http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/subrequest.html

相关问题 更多 >