在金字塔中调用另一种观点
我的目标:在金字塔中,调用另一个视图 - 可调用,并获取Response
对象,但不知道该视图的任何细节 - 可调用。
在我的Pyramid应用程序中,假设我有一个使用view_config装饰器定义的视图“foo”:
@view_config(route_name="foo",
renderer="foo.jinja2")
def foo_view(request):
return {"whereami" : "foo!"}
现在说我想将“bar”路由到一个视图,该视图暂时执行相同的操作,所以它在内部调用foo_view
并返回它的Response:
@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
相同的渲染器。 但是这是不好的,因为我现在必须通过复制渲染器值和必须知道被调用视图的渲染器来重复自己。
所以,我希望Pyramid中有一些函数允许调用另一个视图 - 可调用并返回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使客户端重定向到目标路由是我试图避免的,我想“内部”重定向)。
是的。 有一些担忧
这就是为什么你不应该将视图视为函数,除非你知道你在做什么
金字塔创建者为服务器端重定向做了很棒的工具 - http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/subrequest.html
我也为此苦苦挣扎。 我有一个使用render_to_response方法的解决方案,但我确信有一个“更正确”的方法来做到这一点。 然而,在有人发布之前,我是这样处理的:
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)
这需要使用渲染器,但通过在原始视图的返回值中声明渲染器,您可以在不知道它是什么的情况下在另一个视图中检索它。 我怀疑需要做到这一点不容易找到,因为还有其他更好的方法来完成此解决方案所解决的任务。
另一个缺点是它依赖直接导入视图可调用。 如果可以通过路线直接查找,那将会很好。
这里的金字塔文档指出,将view_config
的name
关键字参数view_config
将导致该视图由函数本身(而不是字符串)进行注册:
这样的注册...意味着视图名称将是* my_view *
所以,在你的情况下,你应该能够直接使用pyramid.view.render_view
或pyramid.view.render_view_to_response
引用foo_view
:
@view_config(route_name="bar")
def bar_view(request):
return pyramid.views.render_view_to_response(None, request, name=foo_view)
更新:
是的,你的权利, 通过视图功能不起作用 。
这很有趣,但拿你的示例代码并将route_name
应用于配置对我来说并不适用。 然而,下面的例子,只是给视图一个name
设置路由URL并给视图一个名字。 以这种方式render_view_to_response
按照广告方式工作。 命名,你的意见可能不是你想要的,但是这个配置完成了与你的示例代码相同的事情,而没有添加配置。
@view_config(name="foo")
def foo_view(request):
# returning a response here, in lieu of having
# declared a renderer to delegate to...
return Response('Where am i? `{0[whereami]}'.format({"whereami" : "foo!"}))
@view_config(name="bar")
def bar_view(request):
# handles the response if bar_view has a renderer
return render_view_to_response(None, request, name='foo')
@view_config(name="baz")
def baz_view(request):
# presumably this would not work if foo_view was
# not returning a Response object directly, as it
# skips over the rendering part. I think you would
# have to declare a renderer on this view in that case.
return foo_view(request)
if __name__ == '__main__':
config = Configurator()
config.scan()
app = config.make_wsgi_app()
serve(app, host='127.0.0.1', port='5000')
链接地址: http://www.djcxy.com/p/69089.html