Web Controllers
Routing
odoo.http.route(route=None, **kw)
装饰器将装饰方法标记为请求的处理程序。 该方法必须是Controller
子类的一部分。
Parameters :
route:-- 字符串或数组。 路径部分将确定哪些http请求将与装饰方法匹配。 可以是单个字符串或字符串数组。 有关路由表达格式的信息,请参阅werkzeug的路由文档(http://werkzeug.pocoo.org/docs/routing/)。
type:请求的类型可以是http
或json
。
auth:--身份验证方法的类型,可以是以下内容:
user
:必须对用户进行身份验证,并使用用户的权限执行当前请求。
public
:用户可能经过认证,也可能未经过认证。 如果不是,则使用共享的公共用户执行当前请求。
none
:即使没有数据库,该方法也始终处于活动状态。 主要由框架和认证模块使用。 请求代码将没有任何访问数据库的工具,也没有任何配置指示当前数据库或当前用户。
methods:-- 此路由适用的一系列http方法。 如果未指定,则允许所有方法。
cors:-- Access-Control-Allow-Origin cors指令值。
csrf(bool) --
是否应为路由启用CSRF保护。
默认为True
。 请参阅CSRF保护了解更多信息。
CSRF保护
9.0版中的新功能。
Odoo实现基于令牌的CSRF保护。
默认情况下启用CSRF保护,并应用于RFC 7231定义的UNSAFE HTTP方法(
GET
,HEAD
,TRACE
和OPTIONS
以外的所有方法)。
CSRF保护是通过使用不安全方法检查请求来实现的,该方法将名为
csrf_token
的值作为请求的表单数据的一部分。 该值作为验证的一部分从表单中删除,不必由您自己的表单处理考虑。
为不安全的方法添加新控制器时(主要是表格形式的POST):
- 如果表单是在Python中生成的,则可以通过
request.csrf_token()
获得csrf标记,默认情况下, request
对象在QWeb(python)模板中可用,可能必须添加 如果您没有使用QWeb,请明确说明。
如果表单是在Javascript中生成的,则CSRF令牌默认添加到QWeb(js)呈现上下文为csrf_token
,否则在web.core
模块上以csrf_token
的形式提供:
require('web.core').csrf_token
如果端点可以被外部方(而不是来自Odoo)调用,例如 它是REST API或webhook,必须在端点上禁用CSRF保护。 如果可能,您可能希望实现其他请求验证方法(以确保它不被不相关的第三方调用)。
Request
请求开始时,在odoo.http.request
上自动设置请求对象
class odoo.http.WebRequest(httprequest)
所有Odoo Web请求类型的父类,主要处理请求对象的初始化和设置(调度本身必须由子类处理)
Parameters:htttprequest(
werkzeug.wrappers.BaseRequest
)--一个包装好的werkzeug Request对象
httprequest
提供给请求的原始werkzeug.wrappers.Request
对象
params
请求参数的mapping
,通常不是很有用,因为它们作为关键字参数直接提供给处理程序方法
cr
为当前方法调用初始化的cursor
。
当前请求使用none
身份验证时访问游标将引发异常。
context
mapping
当前请求的上下文值
env
Environment
绑定到当前请求。
session
OpenERPSession
保存当前http会话的HTTP会话数据
debug
指示当前请求是否处于“调试”模式
registry
链接到此请求的数据库的注册表。 如果当前请求使用none
身份验证,则可以为None
。
自8.0版以来不推荐使用:使用env
db
数据库链接到此请求。 如果当前请求使用none身份验证,则可以为None。
csrf_token(time_limit=3600)
生成并返回当前会话的CSRF令牌
Parameters:time_limit(
time_limit
)--CSRF令牌只应在指定的持续时间(秒)内有效,默认为1h,无权限,只要当前用户的会话是有效的,令牌才有效。
Returns:ASCII token string
def csrf_token(self, time_limit=3600):
""" Generates and returns a CSRF token for the current session
:param time_limit: the CSRF token should only be valid for the
specified duration (in second), by default 1h,
``None`` for the token to be valid as long as the
current user's session is.
:type time_limit: int | None
:returns: ASCII token string
"""
token = self.session.sid
max_ts = '' if not time_limit else int(time.time() + time_limit)
msg = '%s%s' % (token, max_ts)
secret = self.env['ir.config_parameter'].sudo().get_param('database.secret')
assert secret, "CSRF protection requires a configured database secret"
hm = hmac.new(str(secret), msg, hashlib.sha1).hexdigest()
return '%so%s' % (hm, max_ts)
class odoo.http.HttpRequest(*args)
http请求类型的处理程序。
匹配的路由参数,查询字符串参数,表单参数和文件作为关键字参数传递给处理程序方法。
如果名称冲突,路由参数具有优先权。
处理程序方法的结果可以是:
- 一个虚假值,在这种情况下,HTTP响应将是HTTP 204(无内容)
- 一个werkzeug响应对象,按原样返回
str
或unicode
将包装在Response对象中并解释为HTML
make_response(data, headers=None, cookies=None)
帮助非HTML响应,或带有自定义响应标头或Cookie的HTML响应。
虽然返回非HTML数据,处理程序只能返回要作为字符串发送的页面的HTML标记,但是它们需要创建完整的响应对象,否则客户端将无法正确解释返回的数据。
Parameters:
data (basestring
) --response body
headers ([(name, value)]) -- HTTP headers to set on the response
cookies (collections.Mapping)-- cookies to set on the client
not_found(description=None)
HTTP 404(未找到)响应的快捷方式
render(template, qcontext=None, lazy=True, **kw)
懒惰呈现QWeb模板。
给定模板的实际呈现将在调度结束时发生。 同时,模板和/或qcontext可以被改变或甚至被静态响应替换。
Parameters:
template (basestring) -- template to render
qcontext (dict) -- Rendering context to use
lazy(bool) - 是否应该将模板渲染推迟到最后一刻
kw - 转发给werkzeug的Response对象
class odoo.http.JsonRequest(*args)
通过HTTP请求JSON-RPC 2的处理程序
- 方法被忽略
- params必须是JSON对象(不是数组),并作为关键字参数传递给处理程序方法
- 处理程序方法的结果作为JSON-RPC
result
返回并包装在JSON-RPC响应中
请求成功:
--> {"jsonrpc": "2.0",
"method": "call",
"params": {"context": {},
"arg1": "val1" },
"id": null}
<-- {"jsonrpc": "2.0",
"result": { "res1": "val1" },
"id": null}
请求生成错误
--> {"jsonrpc": "2.0",
"method": "call",
"params": {"context": {},
"arg1": "val1" },
"id": null}
<-- {"jsonrpc": "2.0",
"error": {"code": 1,
"message": "End user error message.",
"data": {"code": "codestring",
"debug": "traceback" } },
"id": null}
Response
class odoo.http.Response(*args, **kw)
响应对象通过控制器路由链传递。
除了werkzeug.wrappers.Response
参数之外,此类的构造函数还可以为QWeb Lazy Rendering采用以下附加参数。
Parameters:
template(basestring
) - 要渲染的模板
qcontext(dict
) - 渲染要使用的上下文
uid(int
) - 用于ir.ui.view渲染调用的用户ID,无使用请求的用户(默认)
这些属性在Response对象上可用作参数,并且可以在呈现之前随时更改
还公开了werkzeug.wrappers.Response
的所有属性和方法。
render()
呈现Response的模板,返回结果
flatten()
强制呈现响应模板,将结果设置为响应主体并取消设置template
Controllers
Controllers 需要提供可扩展性,就像Model一样,但不能使用与先决条件相同的机制(带有已加载模块的数据库)可能尚未可用(例如,没有创建数据库,或者没有选择数据库)。
因此,Controllers提供了自己的扩展机制,与模型分离:
Controllers是通过继承而创建的
class odoo.http.Controller
并定义用route()
修饰的方法:
class MyController(odoo.http.Controller):
@route('/some_url', auth='public')
def handler(self):
return stuff()
要覆盖控制器,从其类继承并覆盖相关方法,必要时重新公开它们:
class Extension(MyController):
@route()
def handler(self):
do_before()
return super(Extension, self).handler()
使用route()进行装饰是必要的,以保持方法(和路线)可见:如果重新定义方法而不进行装饰,则将“未发布”
所有方法的装饰器组合在一起,如果重写方法的装饰器没有参数将保留所有先前的参数,任何提供的参数将覆盖先前定义的参数,例如:
class Restrict(MyController):
@route(auth='user')
def handler(self):
return super(Restrict, self).handler()
将/ some_url
从公共身份验证更改为用户(需要登录)