zef*_*ciu 5 python inheritance pyramid
我正在创建一个使用遍历的基于金字塔的简单CMS.有一种叫做类Collection,它有一些子类一样NewsCollection,GalleriesCollection等等.
我需要两种视图来显示这些集合.frontent,html视图和后端json视图(管理面板使用dgrid显示数据).后端视图可以是通用的 - 它会在每种情况下转储json数据.前端视图不应该 - 每种数据都会有一个自定义模板.
问题是:当我配置这样的视图时:
@view_config(context=Collection, xhr=True, renderer='json', accept='application/json')
Run Code Online (Sandbox Code Playgroud)
它工作正常.但是,只要我添加为此配置的任何视图NewsCollection优先.即使我专门将谓词与上述配置(例如accept='text/html')相冲突,仍然不会调用上述视图.相反,我会得到一个'谓词不匹配'.
我的问题是 - Collection当有视图时,我可以做任何事情来配置视图NewsCollection吗?或者我是否必须使用其他设计(如url dispatch或为不同的资源类型多次添加相同的视图)
我试图构建一个非常相似的系统,并发现了同样的问题 - 事实上,这是Pyramid bug跟踪器中的票:https://github.com/Pylons/pyramid/issues/409
简而言之,并非金字塔中的所有视图谓词都是相同的 - 这context是一种特殊情况.首先使用视图匹配视图context,然后使用其他谓词缩小选择范围.
还有一个最近的拉取请求会使Pyramid按照你(和我)的预期行事 - 然而,从讨论中我看到,由于可能的性能权衡,它不太可能被采用.
(更新:拉动请求已于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):
....
Run Code Online (Sandbox Code Playgroud)