请求和响应对象¶
备注
本章改编自 WebOb 文件,最初由伊恩·比金撰写。
Pyramid 使用 WebOb 包作为ITS request 和 response 对象实现。这个 request 对象,该对象传递给 Pyramid view 是一个实例, pyramid.request.Request 类,它是 webob.request.Request 。这个 response 从 Pyramid view renderer 是一个实例, pyramid.response.Response 类的子类,它是 webob.response.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请求方法,例如,
GET,POSTreq.GETA multidict 查询字符串中的所有变量。
req.POSTA multidict 请求主体中的所有变量。只有当请求是
POST这是一个表格提交。req.paramsA multidict 把所有的东西结合在一起
req.GET和req.POST.req.body请求正文的内容。它以字符串形式包含整个请求主体。当请求是
POST那就是 not 表单提交或请求,如PUT. 你也可以得到req.body_file对于类似文件的对象。req.json_bodyJSON解码了请求主体的内容。见 处理JSON编码的请求体 .
req.cookies所有饼干的简单字典。
req.headers所有标题的字典。这本词典不区分大小写。
req.urlvarsandreq.urlargsreq.urlvars是与请求URL关联的关键字参数。req.urlargs是位置参数。这些是由如下产品设置的 Routes 和 Selector .
另外,对于标准HTTP请求头,通常有如下属性: req.accept_language , req.content_length 和 req.user_agent . 这些属性公开了 解析 每个头的形式,无论解析有什么意义。例如, req.if_modified_since 返回A datetime 对象(如果未提供头,则为无)。
备注
完整的API文档 Pyramid 请求对象在中可用 pyramid.request .
由添加到请求的特殊属性 Pyramid¶
除了标准 WebOb 属性, Pyramid 向每个请求添加特殊属性: context , registry , root , subpath , traversed , view_name , virtual_root , virtual_root_path , session , matchdict 和 matched_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=10req.hostURL中的主机信息,例如,
localhostreq.host_url主机的URL,例如,
http://localhostreq.application_url应用程序的URL(仅
SCRIPT_NAME路径的一部分,而不是PATH_INFO),例如,http://localhost/appreq.path_url应用程序的URL,包括
PATH_INFO,例如,http://localhost/app/blogreq.path网址包括
PATH_INFO没有主机或方案,例如,/app/blogreq.path_qs网址包括
PATH_INFO以及查询字符串,例如,/app/blog?id=10req.query_stringURL中的查询字符串,例如,
id=10req.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.POST , req.GET , req.params 和 req.cookies 将包含文本并假定使用UTF-8字符集生成。客户 can 用类似的符号表示字符集 Content-Type: application/x-www-form-urlencoded; charset=utf8 但是浏览器很少设置。可以使用重置现有请求的字符集 newreq = req.decode('utf-8') 或在实例化期间 Request(environ, charset='utf8') .
多重字典¶
WebOB请求的几个属性是多层次结构(例如 request.GET , request.POST 和 request.params )multict是一个字典,其中一个键可以有多个值。最典型的例子是 ?pref=red&pref=blue ; pref 变量有两个值: red 和 blue .
当你这样做的时候 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__ 模块:
1from mypackage.models import DBSession
2
3from pyramid.events import subscriber
4from pyramid.events import NewRequest
5
6def cleanup_callback(request):
7 DBSession.remove()
8
9@subscriber(NewRequest)
10def add_cleanup_callback(event):
11 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.remove 当 pyramid_tm middleware 配置到应用程序中。
更多细节¶
有关请求对象API的更多详细信息如下。
pyramid.request.RequestAPI文档WebOb documentation <https://docs.pylonsproject.org/projects/webob/en/latest/index.html> ②A的所有方法和属性
webob.RequestWebOB文档中的文档将与由 Pyramid .
响应¶
这个 Pyramid 响应对象可以导入为 pyramid.response.Response 。此类是 webob.reponse.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.charset)response.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)这使得响应在给定的秒数内可缓存,或者如果
seconds是0那么响应是不可缓存的(这也设置了Expires标题)。response(environ, start_response)响应对象是一个wsgi应用程序。作为一个应用程序,它根据您创建它的方式进行操作。它 can 如果通过,则执行条件响应
conditional_response=True在实例化(或稍后设置该属性)时。它还可以执行头部和范围请求。
报头¶
与请求类似,大多数HTTP响应头都是作为属性提供的。这些是解析的,所以您可以执行以下操作 response.last_modified = os.path.getmtime(filename) .
详情见 webob.response API文档。
实例化响应¶
当然,大多数时候你只是想 make 反应。通常,响应的任何属性都可以作为关键字参数传递给类,例如:
1from pyramid.response import Response
2response = 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 ,这样您就可以以相同的方式操作实例。一个典型的例子是:
1from pyramid.httpexceptions import HTTPNotFound
2from pyramid.httpexceptions import HTTPMovedPermanently
3
4response = HTTPNotFound('There is no such resource')
5# or:
6response = HTTPMovedPermanently(location=new_url)
更多细节¶
有关响应对象API的更多详细信息,请参见 pyramid.response 文档。有关异常响应的更多详细信息,请参见 pyramid.httpexceptions API文档。这个 WebOb documentation 也是有用的。