如果在Pyramid中配置了类的视图,是否可以使用为超类配置的视图?

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或为不同的资源类型多次添加相同的视图)

Ser*_*gey 6

我试图构建一个非常相似的系统,并发现了同样的问题 - 事实上,这是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)