【问题标题】:In Pyramid, how can I use a different renderer based on contents of context?在 Pyramid 中,如何根据上下文内容使用不同的渲染器?
【发布时间】:2024-10-11 07:50:01
【问题描述】:

我想根据有关产品的可用信息显示 3 种不同的产品页面布局。使用遍历我有一个名为ProductFinder 的类,它可以获取所有信息。例如,用户转到 domain/green/small ,ProductFinder 将列出我的数据库中所有绿色和小型的产品。此列表是 ProductFinder 类中的 self.products。在我的__init__.py 中,我添加了这一行:

config.add_view('app.views.products', name='')

在 products.py 我有:

from pyramid.view import view_config
@view_config(context='app.models.ProductFinder', renderer='productpage.mako')
def products(context, request):
    return dict(page=context)

根据 context.products 中的内容,我想渲染一个不同的 mako。在 Pylons 中,我会做类似的事情:

def products(context, request):
    if len(context.products) == 1:
        return render("oneproduct.mako")
    elif len(context.product) == 2:
        return render("twoproducts.mako")

那么如何根据上下文的内容呈现不同的模板呢?

【问题讨论】:

  • 你的第一行“config.add_view('app.views.products', name='')”很可能不是你想要的。 @view_config 是我认为您在这里真正关心的唯一一个。

标签: python pyramid traversal mako


【解决方案1】:

我首先要说这种看起来像是你想在你的模板中处理的事情。

然而,您几乎可以以任何您想要的方式影响哪个渲染器被用作视图查找的一部分。您可能已经知道可以为多个视图使用同一个视图处理程序,您只需要帮助 Pyramid 确定使用哪一个即可。

例如:

from pyramid.view import view_config

def ProductLengthPredicate(length):
    def check_length(context, request):
        return len(context.products) == length
    return check_length

@view_config(context='app.models.ProductFinder', renderer='oneproduct.mako',
             custom_predicates=(ProductLengthPredicate(1),))
@view_config(context='app.models.ProductFinder', renderer='twoproducts.mako',
             custom_predicates=(ProductLengthPredicate(2),))
@view_config(context='app.models.ProductFinder', renderer='manyproducts.mako')
def products(context, request):
    return dict(page=context)

注意。有些人可能对这里的render_to_response 方法更感兴趣,因为那样他们就不会依赖custom_predicates。但这当然取决于你!

@view_config(context='app.models.ProductFinder', renderer='manyproducts.mako')
def products(context, request)
    opts = dict(page=context)
    if len(context.products) == 1:
        return render_to_response('oneproduct.mako', opts, request)
    if len(context.products) == 2:
        return render_to_response('twoproducts.mako', opts, request)
    return opts

这是可行的,因为如果您的视图返回 Response()(这正是 render_to_response 所做的事情),Pyramid 将忽略渲染器。

【讨论】:

  • 非常感谢。自定义谓词正是我想要的
【解决方案2】:

我不确定这是否是好方法,但您可能可以使用request.override_renderer = 'oneproduct.mako'

如果只是根据数量以不同的方式展示您的产品,您应该在模板中做出决定。

【讨论】:

  • 不错的简单解决方案!
最近更新 更多