请求和响应对象

注解

本章改编自 WebOb 文件,最初由伊恩·比金撰写。

Pyramid 使用 WebOb 包作为其基础 requestresponse 对象实现。这个 request 传递给 Pyramid view 是的实例 pyramid.request.Request 类,它是 webob.Request . 这个 response 从A返回 Pyramid view renderer 是的实例 pyramid.response.Response 类,它是 webob.Response 班级。用户还可以返回 pyramid.response.Response 必要时直接从视图中查看。

webob是一个独立于 Pyramid 一组独立的作者和一个完全独立的 set of documentation . Pyramid 向标准WebOB请求添加一些功能,这些功能记录在 pyramid.request API文档。

Webob为HTTP请求和响应提供对象。具体来说,它通过包装 WSGI 请求环境和响应状态、头列表和app-iter(body)值。

WebOB请求和响应对象为解析wsgi请求和形成wsgi响应提供了许多便利。Webob是一种表示“原始”WSGi请求和响应的好方法。但是,在本文档中,作为 Pyramid 通常不需要直接使用Webob的与wsgi相关的特性。这个 reference documentation 然而,显示了许多以这种方式创建请求和使用响应对象的示例。

请求

请求对象是 WSGI environ dictionary . 此字典包含每个头的键、描述请求的键(包括路径和查询字符串)、请求主体的类似文件的对象以及各种自定义键。您可以随时使用 req.environ .

请求对象的一些最重要和最有趣的属性如下。

req.method
请求方法,例如, GETPOST
req.GET
A multidict 查询字符串中的所有变量。
req.POST
A multidict 请求主体中的所有变量。只有当请求是 POST 这是一个表格提交。
req.params
A multidict 把所有的东西结合在一起 req.GETreq.POST .
req.body
请求正文的内容。它以字符串形式包含整个请求主体。当请求是 POST 那就是 not 表单提交或请求,如 PUT . 你也可以得到 req.body_file 对于类似文件的对象。
req.json_body
JSON解码了请求主体的内容。见 处理JSON编码的请求体 .
req.cookies
所有饼干的简单字典。
req.headers
所有标题的字典。这本词典不区分大小写。
req.urlvars and req.urlargs
req.urlvars 是与请求URL关联的关键字参数。 req.urlargs 是位置参数。这些是由如下产品设置的 RoutesSelector .

另外,对于标准HTTP请求头,通常有如下属性: req.accept_languagereq.content_lengthreq.user_agent . 这些属性公开了 解析 每个头的形式,无论解析有什么意义。例如, req.if_modified_since 返回A datetime 对象(如果未提供头,则为无)。

注解

完整的API文档 Pyramid 请求对象在中可用 pyramid.request .

由添加到请求的特殊属性 Pyramid

除了标准 WebOb 属性, Pyramid 向每个请求添加特殊属性: contextregistryrootsubpathtraversedview_namevirtual_rootvirtual_root_pathsessionmatchdictmatched_route . 这些属性在 pyramid.request.Request API文档。

URLs

除了这些属性之外,还有几种方法可以获取请求的URL及其部分。我们将显示示例URL的各种值 http://localhost/app/blog?id=10 ,安装应用程序的位置 http://localhost/app .

req.url
带有查询字符串的完整请求URL,例如, http://localhost/app/blog?id=10
req.host
URL中的主机信息,例如, localhost
req.host_url
主机的URL,例如, http://localhost
req.application_url
应用程序的URL(仅 SCRIPT_NAME 路径的一部分,而不是 PATH_INFO ),例如, http://localhost/app
req.path_url
应用程序的URL,包括 PATH_INFO ,例如, http://localhost/app/blog
req.path
网址包括 PATH_INFO 没有主机或方案,例如, /app/blog
req.path_qs
网址包括 PATH_INFO 以及查询字符串,例如, /app/blog?id=10
req.query_string
URL中的查询字符串,例如, id=10
req.relative_url(url, to_application=False)
提供相对于当前URL的URL。如果 to_application 为真,然后相对于 req.application_url .

方法

请求对象的方法记录在 pyramid.request.Request 但是你会发现你不会用很多。以下是一些可能有用的:

Request.blank(base_url)
基于给定的URL创建一个包含空白信息的新请求。这对于子请求和人工请求很有用。您也可以使用 req.copy() 复制现有请求或子请求 req.copy_get() 它复制请求,但始终将其转换为GET(这样子请求共享更安全)。
req.get_response(wsgi_application)
此方法使用此请求调用给定的wsgi应用程序,并返回 pyramid.response.Response 对象。您也可以将其用于子请求或测试。

文本(Unicode)

请求对象的大多数属性都是文本值。中的值 req.POSTreq.GETreq.paramsreq.cookies 将包含文本并假定使用UTF-8字符集生成。客户 can 用类似的符号表示字符集 Content-Type: application/x-www-form-urlencoded; charset=utf8 但是浏览器很少设置。可以使用重置现有请求的字符集 newreq = req.decode('utf-8') 或在实例化期间 Request(environ, charset='utf8') .

多重字典

WebOB请求的几个属性是多层次结构(例如 request.GETrequest.POSTrequest.params )multict是一个字典,其中一个键可以有多个值。最典型的例子是 ?pref=red&pref=bluepref 变量有两个值: redblue .

当你这样做的时候 request.GET['pref'] 你只能回去了 "blue" (最后一个值 pref )此返回的结果可能不是预期的,有时返回字符串,有时返回列表,可能是频繁出现异常的原因。如果你想要 all 返回值,使用 request.GET.getall('pref') . 如果你想确定 一个而且只有一个 使用价值 request.GET.getone('pref') ,如果的值为零或多个,则将引发异常 pref .

当你使用诸如 request.GET.items() 你会回来的 [('pref', 'red'), ('pref', 'blue')] . 将显示所有键/值对。同样地 request.GET.keys() 收益率 ['pref', 'pref'] . multict是元组列表上的一个视图;所有键都是有序的,所有值都是有序的。

多学科的API文档存在于 pyramid.interfaces.IMultiDict .

处理JSON编码的请求体

1.1 新版功能.

pyramid.request.Request.json_body 是返回 JSON -请求主体的解码表示。如果请求没有主体,或者主体不是正确的JSON编码值,那么访问该属性时将引发异常。

当您调用 Pyramid 例如,通过jquery的 $.ajax 函数,它可以用JSON编码的主体发送请求。

使用 request.json_body 相当于:

from json import loads
loads(request.body, encoding=request.charset)

下面介绍如何使用JavaScript构造Ajax请求 jQuery 它允许你使用 request.json_body 当请求发送到 Pyramid 应用:

jQuery.ajax({type:'POST',
             url: 'http://localhost:6543/', // the pyramid server
             data: JSON.stringify({'a':1}),
             contentType: 'application/json'});

当此类请求到达应用程序中的视图时, request.json_body 属性将在视图可调用主体中可用。

@view_config(renderer='string')
def aview(request):
    print(request.json_body)
    return 'OK'

对于上述视图,打印到控制台的内容如下:

{'a': 1}

对于奖励积分,这里有一点客户端代码,它将生成一个请求,该请求具有一个适合通过 request.json_body 使用Python的 urllib2 而不是Javascript Ajax请求:

import urllib2
import json

json_payload = json.dumps({'a':1})
headers = {'Content-Type':'application/json'}
req = urllib2.Request('http://localhost:6543/', json_payload, headers)
resp = urllib2.urlopen(req)

如果您正在执行跨源站资源共享(CORS),则标准要求浏览器执行飞行前HTTP选项请求。最简单的处理方法是添加一个 view_config 对于同一条路线, request_method 设置为 OPTIONS ,并在返回前设置所需的响应头。您可以找到响应头的示例 Access control CORS, Preflighted requests .

请求后清理

有时,当涉及数据库连接时,需要在请求结束时执行一些清理。

例如,假设您有 mypackage Pyramid 使用sqlachemy的应用程序包,您希望在每次请求后删除当前的sqlachemy数据库会话。将以下内容放入 mypackage.__init__ 模块:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from mypackage.models import DBSession

from pyramid.events import subscriber
from pyramid.events import NewRequest

def cleanup_callback(request):
    DBSession.remove()

@subscriber(NewRequest)
def add_cleanup_callback(event):
    event.request.add_finished_callback(cleanup_callback)

注册 cleanup_callback 在请求开始时完成回调(通过 add_cleanup_callback 接收 pyramid.events.NewRequest 每个请求开始时的事件)将导致在请求处理结束时删除dbsession。请注意,在上面的示例中, pyramid.events.subscriber 装修工,装修工 pyramid.config.Configurator.scan() 必须针对您的 mypackage 应用程序初始化期间的包。

注解

这只是一个例子。特别是,没有必要 DBSession.remove 在从生成的应用程序中调用 Pyramid 因为这些都使用 pyramid_tm 包裹。清理工作由 DBSession.removepyramid_tm middleware 配置到应用程序中。

更多细节

有关请求对象API的更多详细信息如下。

  • pyramid.request.Request API文档
  • WebOb documentation <https://docs.pylonsproject.org/projects/webob/en/latest/index.html> ②A的所有方法和属性 webob.Request WebOB文档中的文档将与由 Pyramid .

响应

这个 Pyramid 响应对象可以导入为 pyramid.response.Response . 这个类是 webob.Response 班级。子类不添加或更改任何功能,因此WebOB响应文档也将与此类完全相关。

响应对象有三个基本部分:

response.status
响应代码加上原因消息,比如 200 OK . 要设置不带消息的代码,请使用 status_int ,即 response.status_int = 200 .
response.headerlist
所有标题的列表,比如 [('Content-Type', 'text/html')] . 有个不区分大小写的 multidict 在里面 response.headers 这也允许您访问这些相同的头文件。
response.app_iter
将生成响应内容的可ITable(如列表或生成器)。这也可以作为 response.body (字节) response.text (一个Unicode字符串,由 response.charsetresponse.body_file (像文件一样的物体;写在上面附加在 app_iter

对象中的其他所有内容通常都源于此基础状态。以下是一些亮点:

response.content_type

内容类型 not 包括 charset 参数。

典型用途: response.content_type = 'text/html' .

默认值: response.content_type = 'text/html' .

response.charset
这个 charset 内容类型的参数,它还通知 response.text . response.content_type_params 是所有参数的字典。
response.set_cookie(name, value, max_age=None, path='/', ...)
放饼干。关键字参数控制各种cookie参数。这个 max_age 参数是cookie的生存时间(秒)(也可以使用TimeDelta对象)。这个 Expires 键也将基于 max_age .
response.delete_cookie(name, path='/', domain=None)
从客户端删除cookie。这套 max_age 到0,cookie值到 '' .
response.cache_expires(seconds=0)
这使得响应在给定的秒数内可缓存,或者如果 seconds0 那么响应是不可缓存的(这也设置了 Expires 标题)。
response(environ, start_response)
响应对象是一个wsgi应用程序。作为一个应用程序,它根据您创建它的方式进行操作。它 can 如果通过,则执行条件响应 conditional_response=True 在实例化(或稍后设置该属性)时。它还可以执行头部和范围请求。

报头

与请求类似,大多数HTTP响应头都是作为属性提供的。这些是解析的,所以您可以执行以下操作 response.last_modified = os.path.getmtime(filename) .

详情见 webob.response API文档。

实例化响应

当然,大多数时候你只是想 make 反应。通常,响应的任何属性都可以作为关键字参数传递给类,例如:

1
2
from pyramid.response import Response
response = Response(body='hello world!', content_type='text/plain')

状态默认为 '200 OK' .

价值 content_type 默认为 webob.response.Response.default_content_type ,这就是 text/html . 您可以子类 pyramid.response.Response 并设置 default_content_type 覆盖此行为。

异常响应

以便于错误响应,如 404 Not Found ,模块 pyramid.httpexceptions 包含各种错误响应的类。这些包括无聊但适当的误差体。当在下面使用时,此模块公开的异常 Pyramid ,应从 pyramid.httpexceptions 模块。此导入位置包含子类和替换,这些子类和替换与 webob.exc 模块。

每个类都有名称 pyramid.httpexceptions.HTTP* 在哪里 * 是导致错误的原因。例如, pyramid.httpexceptions.HTTPNotFound 子类 pyramid.response.Response ,这样您就可以以相同的方式操作实例。一个典型的例子是:

1
2
3
4
5
6
from pyramid.httpexceptions import HTTPNotFound
from pyramid.httpexceptions import HTTPMovedPermanently

response = HTTPNotFound('There is no such resource')
# or:
response = HTTPMovedPermanently(location=new_url)

更多细节

有关响应对象API的更多详细信息,请参见 pyramid.response 文档。有关异常响应的更多详细信息,请参见 pyramid.httpexceptions API文档。这个 WebOb documentation 也是有用的。