查看配置

View lookupPyramid 负责查找和调用 view callable . View configuration 控制如何 view lookup 在应用程序中操作。在任何给定的请求期间,视图查找子系统将视图配置信息与请求数据进行比较,以便找到该请求的“最佳”可调用视图。

在前面的章节中,您已经了解了一些简单的视图配置声明,但没有太多的解释。在本章中,我们将详细探讨这个主题。

将资源或URL模式映射到可调用的视图

开发人员 view callable 可在 Pyramid 应用程序通过 view configuration . 视图配置将一个可调用视图与一组语句相关联,这些语句确定要调用视图可调用视图必须为真的一组情况。

视图配置语句是关于 context 资源(或异常)和 request .

视图配置通过以下两种方式之一执行:

查看配置参数

所有形式的视图配置都接受相同的常规参数类型。

在视图配置期间提供的许多参数是 view predicate 争论。视图配置期间使用的视图谓词参数用于缩小 view lookup 将找到可调用的特定视图。

View predicate 属性是视图配置的重要组成部分,它使 view lookup 用于查找和调用适当视图的子系统。视图配置所拥有的谓词属性的数量越大,在调用已注册的可调用视图之前,情况就越具体。提供给特定视图配置的谓词数目越少,调用关联视图可调用的可能性就越大。例如,具有五个谓词的视图将始终在具有两个谓词的视图之前找到和计算。

但这并不意味着 Pyramid 当它发现一个带有不匹配谓词的视图注册时,“停止查找”。如果一组视图谓词不匹配,将为谓词咨询“下一个最特定”视图(如果有),依此类推,直到找到视图,或者没有视图可以与请求匹配。将调用具有一组谓词的第一个视图,所有这些谓词都与请求环境匹配。

如果找不到具有允许其与请求匹配的谓词的视图, Pyramid 将向用户的浏览器返回一个错误,表示“未找到”(404)页面。见 更改未找到视图 有关更改默认值的详细信息 Not Found View .

其他视图配置参数是非谓词参数。它们倾向于修改视图可调用的响应,或者防止由于授权策略而调用视图可调用。在视图配置中存在非谓词参数并不能缩小将调用视图可调用的情况。

非谓词参数

permission

A的名字 permission 用户必须拥有才能调用 view callable . 见 配置视图安全性 有关查看安全性和权限的详细信息。

如果 permission 未提供,没有为此视图注册权限(任何调用方都可以访问该视图)。

attr

视图机械默认使用 __call__ 方法 view callable (或者函数本身,如果视图可调用是函数)以获取响应。这个 attr 值允许您更改用于获取响应的方法属性。例如,如果视图是一个类,并且该类有一个名为 index 你想用这个方法代替类的 __call__ 你会说,返回响应的方法 attr="index" 在视图的视图配置中。当视图定义是一个类时,这是最有用的。

如果 attr 未提供, None 使用(如果视图是函数,则表示函数本身,或者 __call__ 如果视图是类,则调用属性)。

renderer

表示 renderer 将用于构造 response 从关联视图Callable的返回值。

参见

也见 渲染器 .

这是一个单字符串项(例如, json )或表示路径或 asset specification (例如, templates/views.pt )命名为 renderer 实施。如果 renderer 值不包含点 (. ,指定的字符串将用于查找渲染器实现,该渲染器实现将用于从视图返回值构造响应。如果 renderer 值包含一个点 (. ,指定的术语将被视为路径,路径中最后一个元素的文件扩展名将用于查找渲染器实现,该实现将传递完整路径。

当渲染器是路径时,尽管路径通常只是一个简单的相对路径名(例如, templates/foo.pt ,表示名为“foo.pt”的模板位于相对于当前目录的“templates”目录中。 package )-路径可以是绝对路径,从UNIX上的斜线或Windows上的驱动器号前缀开始。路径也可以是 asset specification 形式上 some.dotted.package_name:relative/path ,使其能够处理位于单独包中的模板资产。

这个 renderer 属性是可选的。如果未定义,则假定为“空”渲染器(不执行渲染并将值传递回上游 Pyramid 机械不变)。注意,如果视图可调用本身返回 response (见 查看可调用响应 ,则从不调用指定的呈现器实现。

http_cache

当你提供一个 http_cache 视图配置的值, ExpiresCache-Control 由关联视图可调用生成的响应的头将被修改。价值 http_cache 可能是下列之一:

  • 非零整数。如果它是一个非零整数,它被视为秒数。此秒数将用于计算 Expires 报头和 Cache-Control: max-age 调用此视图的请求的响应参数。例如: http_cache=3600 指示请求浏览器“将此响应缓存一小时”。
  • A datetime.timedelta 实例。如果是 datetime.timedelta 例如,它将被转换为秒数,该秒数将用于计算 Expires 报头和 Cache-Control: max-age 调用此视图的请求的响应参数。例如: http_cache=datetime.timedelta(days=1) 指示请求浏览器“将此响应缓存一天”。
  • 零 (0 )如果值为零,则 Cache-ControlExpires 来自此视图的所有响应中存在的头将被组成,这样客户端浏览器缓存(以及任何中间缓存)将被指示从不缓存响应。
  • 一个二元组。如果是两元组(例如, http_cache=(1, {{'public':True}}) ,元组中的第一个值可以是非零整数或 datetime.timedelta 实例。无论哪种情况,此值都将用作缓存响应的秒数。元组中的第二个值必须是字典。字典中的值将用作 Cache-Control 响应头。例如: http_cache=(3600, {{'public':True}}) 表示“缓存一小时,然后添加” public 到响应“”的缓存控制头。支持的所有键和值 webob.cachecontrol.CacheControl 接口可以添加到字典中。供应 {{'public':True}} 等于调用 response.cache_control.public = True .

提供非元组值作为 http_cache 等于调用 response.cache_expires(value) 在你的视野内。

提供两元组值作为 http_cache 等于调用 response.cache_expires(value[0], **value[1]) 在你的视野内。

如果你想避免影响 Expires 标题,而只希望影响 Cache-Control 头,传递元组为 http_cache 第一个元素是 None ,即 (None, {{'public':True}}) .

require_csrf

CSRF检查将影响未被RFC2616定义为“安全”方法的任何请求方法。在实践中,这意味着get、head、options和trace方法将不受影响地通过,而所有其他方法将需要CSRF。此选项与 pyramid.require_default_csrf 用于控制为CSRF令牌检查哪些请求参数的设置。

此功能需要配置 session factory .

如果此选项设置为 True 然后将为此视图的POST请求启用CSRF检查。所需的令牌将是 pyramid.require_default_csrf 设置,或将回退到 csrf_token .

如果将此选项设置为字符串,则将启用CSRF检查并将其用作所需的令牌,而不管 pyramid.require_default_csrf 设置。

如果此选项设置为 False 然后将禁用CSRF检查,无论 pyramid.require_default_csrf 设置。

此外,如果此选项设置为 True 或者一个字符串,然后启用CSRF原点检查。

自动检查CSRF令牌 更多信息。

1.7 新版功能.

wrapper

这个 view name 不同的 view configuration 将接收此视图的响应正文作为 request.wrapped_body 它自己的属性 requestresponse 此视图作为 request.wrapped_response 其自身请求的属性。使用包装器可以将视图“链接”在一起以形成复合响应。最外层包装视图的响应将返回给用户。将在找到任何视图时找到包装视图。见 查看配置 . 将根据查找顺序找到“最佳”包装视图。在引擎盖下“这个包装器视图是通过 pyramid.view.render_view_to_response(context, request, 'wrapper_viewname') . 包装视图的上下文和请求与内部视图的上下文和请求相同。

如果 wrapper 未提供,未使用包装视图。

decorator

A dotted Python name 用于修饰已注册的 view callable . 将使用可调用视图作为单个参数调用decorator函数。传递的可调用视图将接受 (context, request) . decorator必须返回一个可调用的替换视图,该视图也接受 (context, request) . 这个 decorator 也可以是一个不可重复的装饰器,在这种情况下,它们将按相反的顺序依次应用到视图中。例如::

@view_config(..., decorator=(decorator2, decorator1))
def myview(request):
  ...

类似于直接装饰可调用的视图:

@view_config(...)
@decorator2
@decorator1
def myview(request):
  ...

一个重要的区别是每个修饰符将接收一个响应对象实现 pyramid.interfaces.IResponse 而不是从视图可调用返回的原始值。链中的所有修饰符都必须返回响应对象或引发异常:

def log_timer(wrapped):
    def wrapper(context, request):
        start = time.time()
        response = wrapped(context, request)
        duration = time.time() - start
        response.headers['X-View-Time'] = '%.3f' % (duration,)
        log.info('view took %.3f seconds', duration)
        return response
    return wrapper
mapper
python对象或 dotted Python name 指的是 view mapperNone . 默认情况下是 None 指示视图应使用默认视图映射器。这个插件点对金字塔扩展开发人员很有用,但对于开发股票金字塔应用程序的“平民”来说并不是很有用。别理窗帘后面的那个人。
accept

A media type 这将与 Accept HTTP请求头。如果指定了此值,则它必须是特定的媒体类型,例如 text/htmltext/html;level=1 . 如果媒体类型被 Accept 请求的标题,或者如果 Accept 请求中根本没有设置头,该谓词将匹配。如果这与 Accept 请求的头,视图匹配继续。

如果 accept 未指定,则 HTTP_ACCEPT 在决定是否调用关联的视图可调用时,不考虑HTTP头。

这个 accept 从技术上讲,参数不是谓词,不支持包装 pyramid.config.not_() .

接受标题内容协商 更多信息。

在 1.10 版更改: 指定媒体范围已弃用,将在中删除 Pyramid 2。使用显式媒体类型以避免内容协商中的任何含糊不清。

在 2.0 版更改: 已删除对媒体范围的支持。

exception_only

当该值为 True , the context 参数必须是的子类 Exception . 此标志表示只有 exception view 应该创建,并且如果遍历 context 匹配 context 争论。如果 context 是的子类 Exception 这个值是 False (默认),然后将注册一个视图以匹配遍历 context 也。

1.8 新版功能.

谓词参数

这些参数修改视图查找行为。一般来说,所提供的谓词参数越多,配置视图的使用就越具体、越窄。

name

这个 view name 需要匹配此视图可调用。一 name 参数通常只在应用程序使用 traversal . 读 遍历 了解视图名称的概念。

如果 name 未提供,将使用空字符串(表示默认视图)。

context

表示一个python类的对象,其中 context 资源必须是实例 or 这个 interfacecontext 必须提供资源才能找到和调用此视图。当 context 资源是表示类的实例,或者如果 context 资源提供表示的接口;否则为假。

如果上下文可以将异常子类化,则可以将异常类作为上下文传递。在这种情况下 two 视图将被注册。一个将匹配正常的传入请求,另一个将匹配为 exception view 只有在正常请求处理管道期间引发异常时才会发生。

如果 context 未提供,值 None 使用与任何资源匹配的。

route_name

如果 route_name 如果提供,则仅当指定的路由匹配时才调用视图可调用。

此值必须与 name A的 route configuration 声明(见 URL调度 )必须匹配才能调用此视图。请注意 route 配置引用者 route_name 通常会有一个 *traverse 以其值表示的令牌 pattern ,表示将由 traversal 根据路线的结果 root factory .

如果 route_name 如果未提供,则只有在没有其他路由匹配的情况下才有机会调用视图可调用。这是通过以下方式找到请求/上下文对的时间: resource location 不表示它与任何配置的路由匹配。

request_type

此值应为 interfacerequest 必须提供才能找到和调用此视图。

如果 request_type 未提供,值 None 使用,表示任何请求类型。

这是一个高级功能,不常被“平民”使用。 .

request_method

该值可以是字符串(例如 "GET""POST""PUT""DELETE""HEAD""OPTIONS" )表示HTTP REQUEST_METHOD 或者包含一个或多个这些字符串的元组。带有此参数的视图声明确保只有在 method 请求的属性(即 REQUEST_METHOD 与提供的值匹配。

在 1.4 版更改: "GET" 也意味着这个观点将对 "HEAD" .

如果 request_method 如果未提供,则无论 REQUEST_METHODWSGI 环境。

request_param

该值可以是任何字符串或字符串序列。带有此参数的视图声明确保只有在 request 有一把钥匙在 request.params 字典(HTTP GETPOST 变量)具有与提供的值匹配的名称。

如果提供的任何值具有 = 登录它,例如, request_param="foo=123" 然后是钥匙 (foo )必须同时存在于 request.params 词典, and 该值必须与表达式的右侧匹配 (123 )使视图与当前请求“匹配”。

如果 request_param 未提供,将调用视图,而不考虑 request.params 字典。

match_param

这个参数可以是格式为“key=value”的单个字符串,也可以是包含一个或多个字符串的元组。

此参数确保只有在 request 其中有键/值对 matchdict 等于谓词中提供的值。例如, match_param="action=edit" 需要 action 中的参数 matchdict 匹配表达式的右侧 (edit )使视图与当前请求“匹配”。

如果 match_param 是一个元组,每个键/值对必须匹配才能传递谓词。

如果 match_param 未提供,将调用该视图,而不考虑中的键和值。 request.matchdict .

1.2 新版功能.

containment

该值应该是对python类的引用,或者 interface 上下文资源中的父对象 lineage 必须提供才能找到和调用此视图。资源树中的资源必须具有“位置感知”才能使用此功能。

如果 containment 如果未提供,则在决定是否调用视图可调用时,不会考虑沿袭中的接口和类。

位置感知资源 有关位置感知的更多信息。

xhr

该值应为 TrueFalse . 如果指定了此值并且 True , the WSGI 环境必须具备 HTTP_X_REQUESTED_WITH 页眉(即 X-Requested-With )有价值的 XMLHttpRequest 用于可找到和调用的关联视图。这对于检测jquery、原型和其他javascript库发出的Ajax请求很有用。

如果 xhr 未指定,则 HTTP_X_REQUESTED_WITH 在决定是否调用关联的视图可调用时,不考虑HTTP头。

header

此值表示HTTP头名称或头名称/值对。

如果 header 是指定的,它必须是头名称或 headername:headervalue 一对。

如果 header 指定时不带值(仅空头名称,例如, If-Modified-Since ,只有当HTTP头存在且请求中有任何值时,才会调用该视图。

如果 header is specified, and possesses a name/value pair (e.g., User-Agent:Mozilla/.*), the view will only be invoked if the HTTP header exists and the HTTP header matches the value requested. When the headervalue contains a : (colon), it will be considered a name/value pair (e.g., `` 用户代理:mozilla/* ``Host:localhost )值部分应该是正则表达式。

无论该值是否表示头名称或头名称/值对,头名称的大小写都不重要。

如果 header 如果未指定,则在决定是否调用关联的视图可调用时,不会考虑HTTP头的组成、存在或不存在。

path_info

此值表示将根据 PATH_INFO wsgi环境变量决定是否调用关联的视图可调用。如果regex匹配,则此谓词将 True .

如果 path_info 未指定,wsgi PATH_INFO 在决定是否调用关联视图可调用时不考虑。

check_csrf

如果指定,则此值应为 NoneTrueFalse 或表示“检查名称”的字符串。如果值是 True 或字符串,将执行CSRF检查。如果值是 FalseNone ,不会执行CSRF检查。

如果提供的值是字符串,则该字符串将用作“检查名称”。如果提供的值是 Truecsrf_token 将用作支票名称。

如果执行了CSRF检查,检查值将为 request.POST[check_name] . 此值将与 request.session.get_csrf_token() ,如果这两个值相同,则检查将通过。如果检查通过,则允许执行关联视图。如果检查失败,将不允许执行关联视图。

请注意,使用此功能需要 session factory 已配置。

1.4a2 新版功能.

physical_path

如果指定,则此值应为表示 physical path 通过遍历找到的该谓词匹配为真的上下文。例如, physical_path='/'physical_path='/a/b/c'physical_path=('', 'a', 'b', 'c') . 这不是路径前缀匹配或regex,而是整个路径匹配。当某个对象被遍历到某个视图时,如果您希望始终潜在地显示该视图,这很有用,但是您不能确定它将是哪种类型的对象,因此不能使用 context 谓语。斜杠字符之间或元组元素中的单个路径元素应为资源名称的Unicode表示形式,并且不应以任何方式编码。

1.4a3 新版功能.

effective_principals

如果指定,则此值应为 principal 标识符或主体标识符序列。如果 pyramid.request.Request.effective_principals() 方法指示参数列表中指定的每个主体都存在于当前请求中,此谓词将返回true;否则将返回false。例如: effective_principals=pyramid.security.Authenticatedeffective_principals=('fred', 'group:admins') .

1.4a4 新版功能.

custom_predicates

如果 custom_predicates 必须是对自定义谓词可调用文件的引用序列。当没有一组预定义谓词执行所需操作时,请使用自定义谓词。根据需要,自定义谓词可以与预定义谓词组合。每个自定义谓词可调用应接受两个参数, contextrequest ,应该返回 TrueFalse 在对上下文资源和/或请求进行任意评估之后。如果所有可调用文件都返回 True ,关联的视图可调用将被视为对给定请求可行。

如果 custom_predicates 未指定,未使用自定义谓词。

predicates

在此处传递一个键/值对以使用通过注册的第三方谓词 pyramid.config.Configurator.add_view_predicate() . 可以同时使用多个键/值对。见 查看和路由谓词 有关第三方谓词的详细信息。

1.4a1 新版功能.

反转谓词值

通过将任何谓词值包装在调用中,可以颠倒其含义。 pyramid.config.not_ .

1
2
3
4
5
6
7
from pyramid.config import not_

config.add_view(
    'mypackage.views.my_view',
    route_name='ok',
    request_method=not_('POST')
    )

上面的示例将确保如果请求方法是 not POST ,至少在没有其他视图更具体的情况下。

将谓词值包装在 not_ 可以在接受谓词值的任何位置使用:

1.5 新版功能.

使用添加视图配置 @view_config 装饰者

警告

使用此功能会稍微降低应用程序的启动速度,因为在应用程序启动时会执行更多的工作来扫描视图配置声明。要获得最大的启动性能,请使用中描述的视图配置方法 使用添加视图配置 add_view() 相反。

这个 view_config decorator可用于关联 view configuration 函数、方法或类作为 Pyramid 查看可调用。

下面是一个例子 view_config 居住在 Pyramid 应用程序模块 views.py

1
2
3
4
5
6
7
from resources import MyResource
from pyramid.view import view_config
from pyramid.response import Response

@view_config(route_name='ok', request_method='POST', permission='read')
def my_view(request):
    return Response('OK')

如上所述,使用这个修饰符可以替代添加这个命令式配置节的需要:

1
2
config.add_view('mypackage.views.my_view', route_name='ok',
                request_method='POST', permission='read')

所有参数 view_config 可省略。例如:

1
2
3
4
5
6
7
from pyramid.response import Response
from pyramid.view import view_config

@view_config()
def my_view(request):
    """ My view """
    return Response()

如上面直接提到的那样的注册意味着视图名称将是 my_view ,注册于 context 参数匹配任何资源类型,不使用权限,针对具有任何请求方法、请求类型、请求参数、路由名称或包含的请求注册。

仅仅存在于 @view_config 装饰器不足以执行视图配置。装饰器所做的就是用配置声明“注释”函数,而不是处理它们。使 Pyramid 处理你的 pyramid.view.view_config 声明,你 must 使用 scan A方法 pyramid.config.Configurator

1
2
3
# config is assumed to be an instance of the
# pyramid.config.Configurator class
config.scan()

请看 声明性配置 有关使用诸如 view_config .

configuration_module 对于 scan() 方法。例如,该方法允许您提供 package 更好控制的理由 哪一个 将扫描代码。

所有参数 view_config decorator的含义与将它们作为参数传递给 pyramid.config.Configurator.add_view() 方法保存为 view 争论。使用 view_config 装饰是一种形式 declarative configuration ,同时 pyramid.config.Configurator.add_view() 是一种形式 imperative configuration . 然而,他们都做同样的事情。

@view_config 安置

A view_config 可以在应用程序的各个点中放置decorator。

如果视图可调用是一个函数,则它可以用作函数修饰器:

1
2
3
4
5
6
from pyramid.view import view_config
from pyramid.response import Response

@view_config(route_name='edit')
def edit(request):
    return Response('edited!')

如果视图可调用是一个类,那么decorator也可以用作类decorator。当对类应用时,装饰器的所有参数与对函数应用时相同。例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from pyramid.response import Response
from pyramid.view import view_config

@view_config(route_name='hello')
class MyView(object):
    def __init__(self, request):
        self.request = request

    def __call__(self):
        return Response('hello')

不止一个 view_config 装饰师可以堆放在任何数量的其他上面。每个装饰器创建一个单独的视图注册。例如:

1
2
3
4
5
6
7
from pyramid.view import view_config
from pyramid.response import Response

@view_config(route_name='edit')
@view_config(route_name='change')
def edit(request):
    return Response('edited!')

这在两个不同的名称下注册相同的视图。

decorator也可用于类的方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from pyramid.response import Response
from pyramid.view import view_config

class MyView(object):
    def __init__(self, request):
        self.request = request

    @view_config(route_name='hello')
    def amethod(self):
        return Response('hello')

当对类的方法使用decorator时,将为 ,因此类构造函数必须接受两种形式之一的参数列表:单个参数, request 或两个参数, context, request .

修饰的方法必须返回 response .

对类的特定方法使用decorator等同于使用 attr 附加到类本身的装饰器中的参数。例如,上面的注册是由装饰师在 amethod 方法可以等效地写如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from pyramid.response import Response
from pyramid.view import view_config

@view_config(attr='amethod', route_name='hello')
class MyView(object):
    def __init__(self, request):
        self.request = request

    def amethod(self):
        return Response('hello')

使用添加视图配置 add_view()

这个 pyramid.config.Configurator.add_view() 内方法 configuration_module 用于“强制”配置视图(不带 view_config 装饰师)此方法的参数与提供给 view_config 装饰者。例如:

1
2
3
4
5
6
7
8
from pyramid.response import Response

def hello_world(request):
    return Response('hello!')

# config is assumed to be an instance of the
# pyramid.config.Configurator class
config.add_view(hello_world, route_name='hello')

第一个论点,a view callable ,是唯一必需的参数。它必须是视图本身的python对象或 dotted Python name 对这样一个物体。在上面的示例中, view callablehello_world 功能。

当你只使用 add_view() 要添加视图配置,不需要发布 scan 以便视图配置生效。

@view_defaults 班级装饰师

1.3 新版功能.

如果将类用作视图,则可以使用 pyramid.view.view_defaults 类上的类修饰符,以提供每个 @view_config 修饰该类的方法的修饰器。

例如,如果有一个类具有表示“rest actions”的方法,则所有这些方法都映射到相同的路由,但请求方法不同,而不是:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
from pyramid.view import view_config
from pyramid.response import Response

class RESTView(object):
    def __init__(self, request):
        self.request = request

    @view_config(route_name='rest', request_method='GET')
    def get(self):
        return Response('get')

    @view_config(route_name='rest', request_method='POST')
    def post(self):
        return Response('post')

    @view_config(route_name='rest', request_method='DELETE')
    def delete(self):
        return Response('delete')

您可以这样做:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
from pyramid.view import view_defaults
from pyramid.view import view_config
from pyramid.response import Response

@view_defaults(route_name='rest')
class RESTView(object):
    def __init__(self, request):
        self.request = request

    @view_config(request_method='GET')
    def get(self):
        return Response('get')

    @view_config(request_method='POST')
    def post(self):
        return Response('post')

    @view_config(request_method='DELETE')
    def delete(self):
        return Response('delete')

在上面的例子中,我们能够 route_name='rest' 对每个人的调用中的参数 @view_config 因为我们使用了 @view_defaults 类decorator提供参数作为它拥有的每个视图方法的默认值。

传递给的参数 @view_config 将重写传递给的任何默认值 @view_defaults .

这个 view_defaults 类decorator还可以提供 pyramid.config.Configurator.add_view() 当一个修饰类作为它的 view 争论。例如,不是这样:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from pyramid.response import Response
from pyramid.config import Configurator

class RESTView(object):
    def __init__(self, request):
        self.request = request

    def get(self):
        return Response('get')

    def post(self):
        return Response('post')

    def delete(self):
        return Response('delete')

def main(global_config, **settings):
    config = Configurator()
    config.add_route('rest', '/rest')
    config.add_view(
        RESTView, route_name='rest', attr='get', request_method='GET')
    config.add_view(
        RESTView, route_name='rest', attr='post', request_method='POST')
    config.add_view(
        RESTView, route_name='rest', attr='delete', request_method='DELETE')
    return config.make_wsgi_app()

减少 config.add_view 语句,我们可以移动 route_name='rest' 对A的论证 @view_defaults 上的类装饰器 RESTView 班级:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from pyramid.view import view_defaults
from pyramid.response import Response
from pyramid.config import Configurator

@view_defaults(route_name='rest')
class RESTView(object):
    def __init__(self, request):
        self.request = request

    def get(self):
        return Response('get')

    def post(self):
        return Response('post')

    def delete(self):
        return Response('delete')

def main(global_config, **settings):
    config = Configurator()
    config.add_route('rest', '/rest')
    config.add_view(RESTView, attr='get', request_method='GET')
    config.add_view(RESTView, attr='post', request_method='POST')
    config.add_view(RESTView, attr='delete', request_method='DELETE')
    return config.make_wsgi_app()

pyramid.view.view_defaults 接受相同的参数集 pyramid.view.view_config 是的,它们有相同的含义。每个参数传递给 view_defaults 为它正在修饰的类的方法的视图配置提供默认值。

普通的python继承规则适用于通过 view_defaults . 例如:

1
2
3
4
5
6
@view_defaults(route_name='rest')
class Foo(object):
    pass

class Bar(Foo):
    pass

这个 Bar 上面的类将从传递给 view_defaults 装饰师 Foo 班级。要防止这种情况发生,请使用 view_defaults 子类上没有任何参数的decorator:

1
2
3
4
5
6
7
@view_defaults(route_name='rest')
class Foo(object):
    pass

@view_defaults()
class Bar(Foo):
    pass

这个 view_defaults decorator只作为类decorator工作;对函数或方法使用它将产生无意义的结果。

配置视图安全性

如果一个 authorization policy 是活动的,任何 permission 附于 view configuration 将验证在视图查找期间找到的。这将确保当前经过身份验证的用户拥有针对 context 实际调用视图函数之前的资源。下面是在视图配置中使用 add_view()

1
2
3
4
5
# config is an instance of pyramid.config.Configurator

config.add_route('add', '/add.html', factory='mypackage.Blog')
config.add_view('myproject.views.add_entry', route_name='add',
                permission='add')

当一个 authorization policy 如果启用,此视图将使用 add 许可。视图将 不叫 如果用户不拥有 add 相对于当前的权限 context . 相反地 forbidden view 结果将按照 使用权限保护视图 .

NotFound 错误

能够调试是很有用的 NotFound 由于应用程序注册表配置错误而意外出现错误响应。要调试这些错误,请使用 PYRAMID_DEBUG_NOTFOUND 环境变量或 pyramid.debug_notfound 配置文件设置。未找到视图的详细信息将打印到 stderr ,并且错误的浏览器表示将包含相同的信息。见 环境变量和 .ini 文件设置 有关如何以及在何处设置这些值的详细信息。

接受标题内容协商

这个 accept 参数 pyramid.config.Configurator.add_view() 可用于控制 view lookup 通过根据HTTP发送到不同的视图 Accept 请求头。考虑下面的示例,其中配置了三个视图。

from pyramid.httpexceptions import HTTPNotAcceptable
from pyramid.view import view_config

@view_config(accept='application/json', renderer='json')
@view_config(accept='text/html', renderer='templates/hello.jinja2')
def myview(request):
    return {
        'name': request.GET.get('name', 'bob'),
    }

@view_config()
def myview_unacceptable(request):
    raise HTTPNotAcceptable

每个视图依赖于 Accept 触发相应响应呈现器的头。当客户端指定头(如 Accept: text/*Accept: application/json, text/html;q=0.9 其中只有一个视图匹配,或者根据首选项确定哪一个视图应该获胜。类似地,如果客户机指定了一个没有注册视图来处理的媒体类型,例如 Accept: text/plain ,它会落到 myview_unacceptable 并提高 406 Not Acceptable .

在一些情况下,客户可以指定 Accept 标题使它不清楚哪个视图应该获胜。例如:

  • Accept: */* .
  • 具有相同质量的多个可接受媒体类型。
  • 遗失 Accept 标题。
  • 无效的 Accept 标题。

在这些情况下,首选视图没有明确定义(参见 RFC 7231#section-5.3.2Pyramid 将随机选择一个。这可以通过告诉 Pyramid 通过使用,不同媒体类型之间的首选相对顺序是什么 pyramid.config.Configurator.add_accept_view_order() . 例如:

from pyramid.config import Configurator

def main(global_config, **settings):
    config = Configurator(settings=settings)
    config.add_accept_view_order('text/html')
    config.add_accept_view_order(
        'application/json',
        weighs_more_than='text/html',
    )
    config.scan()
    return config.make_wsgi_app()

现在, application/json 在客户不清楚的情况下,应始终首选视图。

默认接受排序

Pyramid 将始终使用相同的视图对多个视图进行排序 (name, context, route_name) 首先根据 accept 报盘。对于具有相同功能的任何媒体类型产品 type/subtype ,带有参数的报价将比裸报价更重。 type/subtype 报盘。这意味着 text/plain;charset=utf8 将始终在之前提供 text/plain .

默认情况下,在给定的 type/subtype ,报价单未指明。例如, text/plain;charset=utf8 对战 text/plain;charset=latin1 随机排序。同样,在不同的媒体类型之间,除了下面描述的默认值之外,订单也是未指定的。例如, image/jpeg 对战 image/png 对战 application/pdf . 在这些情况下,可以使用 pyramid.config.Configurator.add_accept_view_order() . 例如,排序 text/plain 高于 text/html 更喜欢 charset=utf8 相对A charset=latin-1text/plain 媒体类型:

config.add_accept_view_order('text/html')
config.add_accept_view_order('text/plain;charset=latin-1')
config.add_accept_view_order('text/plain', weighs_more_than='text/html')
config.add_accept_view_order('text/plain;charset=utf8', weighs_more_than='text/plain;charset=latin-1')

尝试跨特定级别对接受头进行排序是一个错误。你只能对 type/subtype 反对另一个 type/subtype 不反对 type/subtype;params . 这是一个很难的要求。

默认情况下, Pyramid 为视图定义了一个非常简单的优先级排序,它比JSON更喜欢人类可读的响应:

  • text/html
  • application/xhtml+xml
  • application/xml
  • text/xml
  • text/plain
  • application/json

与Web浏览器相比,API客户端往往能够用更多的控制来指定其所需的头文件,并且可以指定正确的头文件。 Accept 值(如有必要)。因此,这种排序的动机是为了优化可读性。以上未列出的媒体类型在 view lookup 在其他相似的观点之间。可以使用覆盖默认值 pyramid.config.Configurator.add_accept_view_order() 如上所述。

影响HTTP缓存

1.1 新版功能.

当一个非``无`` http_cache 参数传递到视图配置,金字塔将设置 ExpiresCache-Control 结果响应中的响应头,导致浏览器缓存响应数据一段时间。见 http_cache 在里面 非谓词参数 允许值及其含义。

有时,由于从视图返回响应而设置这些头是不可取的,即使您希望用具有 http_cache . 也许视图代码中有一个替代分支,它返回一个永远不可缓存的响应,“普通”分支返回一些应该始终可缓存的响应。如果是这样,设置 prevent_auto 的属性 response.cache_control 对象设置为非“false”值。例如,下面的视图可调用配置为 @view_config 指示来自视图的任何响应的装饰器应缓存3600秒。但是,视图本身会阻止发生缓存,除非 should_cache 获取或发布变量:

from pyramid.view import view_config

@view_config(http_cache=3600)
def view(request):
    response = Response()
    if 'should_cache' not in request.params:
        response.cache_control.prevent_auto = True
    return response

请注意 http_cache 除非使用 prevent_auto .

您也可以关闭 http_cache 完全在金字塔应用程序生存期内。为此,请设置 PYRAMID_PREVENT_HTTP_CACHE 环境变量或 pyramid.prevent_http_cache 配置值设置为真值。有关详细信息,请参阅 阻止HTTP缓存 .

注意这个设置 pyramid.prevent_http_cache 对缓存应用程序代码本身设置的头没有影响。它只会阻止缓存头,这些头是由金字塔HTTP缓存机制设置的,该机制是由于 http_cache 视图配置的参数。

调试视图配置

pviews :显示给定URL的匹配视图 有关如何显示可能与给定URL匹配的每个视图可调用文件的信息。这是一种有效的方法来弄清楚为什么调用一个特定的视图可调用项而不是您想要调用的视图。