在Pyramid中,如何根据上下文内容使用不同的渲染器?
我有三种不同的产品页面布局,想根据产品的信息来显示不同的页面。为了获取所有信息,我使用了一个叫做 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
所做的事情。