我正在创建一个使用遍历的基于金字塔的简单CMS。有一个名为Collection
的类,它有一些子类,如NewsCollection
,GalleriesCollection
等。
我需要两种视图来显示这些集合。 frontent,html视图和后端json视图(管理面板使用dgrid显示数据)。后端视图可以是通用的 - 它会在每种情况下转储json数据。前端视图不应该 - 每种数据都会有一个自定义模板。
问题是:当我配置这样的视图时:
@view_config(context=Collection, xhr=True, renderer='json', accept='application/json')
它正常工作。但是,只要我添加为NewsCollection
配置的任何视图,此视图就会优先。即使我特意将谓词与上述配置冲突(例如accept='text/html'
),仍然不会调用上面的视图。相反,我会得到一个“谓词不匹配”。
我的问题是 - 如果还有Collection
的观看次数,我是否可以执行任何操作来调用为NewsCollection
配置的视图?或者我是否必须使用其他设计(例如 url dispatch 或为不同的资源类型多次添加相同的视图)
答案 0 :(得分:6)
我试图构建一个非常相似的系统并发现同样的问题 - 事实上,这是Pyramid bug跟踪器中的票证:https://github.com/Pylons/pyramid/issues/409
简而言之,并非金字塔中的所有视图谓词都相同 - context
是一种特殊情况。首先使用context
匹配视图,然后使用其他谓词缩小选择范围。
还有一个最近的pull request会让金字塔表现得像你(和我)所期望的那样 - 然而,从讨论中我看到,由于可能的性能权衡,它不太可能被采用。
(更新:拉动请求已于2013年3月合并,所以我猜它应该可以在1.4版本之后发布)
解决方法是使用自定义谓词:
def context_implements(*types):
"""
A custom predicate to implement matching views to resources which
implement more than one interface - in this situation Pyramid has
trouble matching views to the second registered interface. See
https://github.com/Pylons/pyramid/issues/409#issuecomment-3578518
Accepts a list of interfaces - if ANY of them are implemented the function
returns True
"""
def inner(context, request):
for typ in types:
if typ.providedBy(context):
return True
return False
return inner
@view_config(context=ICollection,
custom_predicates=(context_implements(INewsCollection),)
)
def news_collection_view(context, request):
....