在Pyramid中,如何根据上下文内容使用不同的渲染器?

9 投票
2 回答
3229 浏览
提问于 2025-04-16 20:41

我有三种不同的产品页面布局,想根据产品的信息来显示不同的页面。为了获取所有信息,我使用了一个叫做 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 中的内容,我想渲染一个不同的模板。在 Pylons 中,我会这样做:

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

那么,我该如何根据我的上下文内容来渲染不同的模板呢?

2 个回答

6

我不太确定这样做是否合适,但你可以试试用 request.override_renderer = 'oneproduct.mako' 这个方法。

如果只是根据数量来改变产品的展示方式,那你应该在模板里做这个决定。

12

我先说一下,这种事情通常是在你的模板里处理比较好。

不过,你可以通过很多方式来影响视图查找时使用哪个渲染器。你可能已经知道,多个视图可以使用同一个视图处理器,你只需要帮助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(),Pyramid会忽略渲染器,而这正是render_to_response所做的事情。

撰写回答