Python+Pyramid+Mako:事件上下文、视图上下文和模板上下文有什么区别?

2 投票
1 回答
879 浏览
提问于 2025-04-17 13:13

我一直在努力理解这个问题,但找不到准确的文档来说明。我对在这个Python Pyramid+Mako的设置中,上下文的不同含义感到很困惑。

这里有一些代码片段(如果你需要更多的上下文,请告诉我):

class Root(object):
    request = None
    def __init__(self, request):
        self.request = request

@events.subscriber(events.BeforeRender)
def add_renderer_globals(event):
    event[u'c'] = event[u'request'].tmpl_context
    print u"add_renderer_globals(): request.tmpl_context={0}".format(event[u'request'].tmpl_context)
    print u"add_renderer_globals(): context={0}".format(event[u'context'])

@view.view_config(route_name='login', request_method='GET', renderer='login.mako')
def login_get(context, request):
    print u"login_get(): context={0}".format(context)
    return {}

[...]
cfg = config.Configurator(root_factory=Root,
        package=MyPKG,
        settings=settings,
        session_factory=pyramid_beaker.session_factory_from_settings(settings),
        )

cfg.add_route(name='login', pattern='/login')

cfg.scan()

在我的mako模板中,举个例子,我只有:

Mako template context=${context}

所以我发出一个请求,然后从控制台或浏览器得到了以下输出:

login_get(): context=<MyPKG.Root object at 0x1523c90>
add_renderer_globals(): request.tmpl_context=<pyramid.request.TemplateContext object at 0x12fbc50>
add_renderer_globals(): context=<MyPKG.Root object at 0x1523c90>
Mako template context=<mako.runtime.Context object at 0x15a4950>

我的问题是:这些有什么不同,它们各自的用途是什么?我也很困惑,为什么在语义上,我声明了root_factory=MyPKG.Root,然后在我的视图和订阅者中,它变成了context=MyPKG.Root

感谢任何能帮助我理解的提示。

1 个回答

4

首先,忽略 request.tmpl_context。这个东西其实就是在 request 对象上的一个字典,你可以往里面添加东西,但在 Pyramid 应用中通常不会用到。它是从 Pylons 合并过来的一个“后代”。

使用 Mako 时,有两个 context 对象。第一个是 mako.runtime.Context,这是 Mako 提供的:http://docs.makotemplates.org/en/latest/runtime.html#context

Pyramid 通常会把遍历上下文(MyPKG.Root)作为 context 在你的模板中暴露出来。不过,Mako 已经有一个同名的变量了。:-( 所以,Pyramid 的 context 实际上叫 _context

撰写回答