路由(Routing)
odoo.http.route(route=None, **kw)[source]
Decorator marking the decorated method as being a handler for
requests. The method must be part of a subclass of Controller
.
- route -- string or array. The route part that will determine which http requests will match the decorated method. Can be a single string or an array of strings. See werkzeug's routing documentation for the format of route expression ( http://werkzeug.pocoo.org/docs/routing/ ).
- type -- The type of request, can be
'http'
or'json'
. - auth --
The type of authentication method, can on of the following:
user
: The user must be authenticated and the current request will perform using the rights of the user.public
: The user may or may not be authenticated. If she isn't, the current request will perform using the shared Public user.none
: The method is always active, even if there is no database. Mainly used by the framework and authentication modules. There request code will not have any facilities to access the database nor have any configuration indicating the current database nor the current user.
- methods -- A sequence of http methods this route applies to. If not specified, all methods are allowed.
- cors -- The Access-Control-Allow-Origin cors directive value.
- csrf (bool) --
Whether CSRF protection should be enabled for the route.
Defaults to
True
. See CSRF Protection for more.
CSRF Protection
New in version 9.0.
Odoo implements token-based CSRF protection.
CSRF protection is enabled by default and applies to UNSAFE
HTTP methods as defined by RFC 7231 (all methods other than
GET
, HEAD
, TRACE
and OPTIONS
).
CSRF protection is implemented by checking requests using
unsafe methods for a value called csrf_token
as part of
the request's form data. That value is removed from the form
as part of the validation and does not have to be taken in
account by your own form processing.
When adding a new controller for an unsafe method (mostly POST for e.g. forms):
- if the form is generated in Python, a csrf token is
available via
request.csrf_token() <odoo.http.WebRequest.csrf_token()
, therequest
object is available by default in QWeb (python) templates, it may have to be added explicitly if you are not using QWeb. if the form is generated in Javascript, the CSRF token is added by default to the QWeb (js) rendering context as
csrf_token
and is otherwise available ascsrf_token
on theweb.core
module:require('web.core').csrf_token
- if the endpoint can be called by external parties (not from Odoo) as e.g. it is a REST API or a webhook, CSRF protection must be disabled on the endpoint. If possible, you may want to implement other methods of request validation (to ensure it is not called by an unrelated third-party).
请求(Request)
请求对象在请求开始时被自动设置于 odoo.http.request
class odoo.http.WebRequest(httprequest)[source]
Parent class for all Odoo Web request types, mostly deals with initialization and setup of the request object (the dispatching itself has to be handled by the subclasses)
werkzeug.wrappers.BaseRequest
) -- a wrapped werkzeug Request objecthttprequest
the original werkzeug.wrappers.Request
object provided to the
request
params
Mapping
of request parameters, not generally
useful as they're provided directly to the handler method as keyword
arguments
cr
Cursor
initialized for the current method call.
Accessing the cursor when the current request uses the none
authentication will raise an exception.
context
Mapping
of context values for the current request
env
The Environment
bound to current request.
session
OpenERPSession
holding the HTTP session data for the
current http session
debug
Indicates whether the current request is in "debug" mode
registry
The registry to the database linked to this request. Can be None
if the current request uses the none
authentication.
Deprecated since version 8.0: use env
db
The database linked to this request. Can be None
if the current request uses the none
authentication.
csrf_token(time_limit=3600)[source]
Generates and returns a CSRF token for the current session
None
for the token to be valid as long as the
current user's session is.class odoo.http.HttpRequest(*args)[source]
Handler for the http
request type.
matched routing parameters, query string parameters, form parameters and files are passed to the handler method as keyword arguments.
In case of name conflict, routing parameters have priority.
The handler method's result can be:
- a falsy value, in which case the HTTP response will be an HTTP 204 (No Content)
- a werkzeug Response object, which is returned as-is
- a
str
orunicode
, will be wrapped in a Response object and interpreted as HTML
make_response(data, headers=None, cookies=None)[source]
Helper for non-HTML responses, or HTML responses with custom response headers or cookies.
While handlers can just return the HTML markup of a page they want to send as a string if non-HTML data is returned they need to create a complete response object, or the returned data will not be correctly interpreted by the clients.
- 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)[source]
Shortcut for a HTTP 404 (Not Found) response
render(template, qcontext=None, lazy=True, **kw)[source]
Lazy render of a QWeb template.
The actual rendering of the given template will occur at then end of the dispatching. Meanwhile, the template and/or qcontext can be altered or even replaced by a static response.
- template (basestring) -- template to render
- qcontext (dict) -- Rendering context to use
- lazy (bool) -- whether the template rendering should be deferred until the last possible moment
- kw -- forwarded to werkzeug's Response object
class odoo.http.JsonRequest(*args)[source]
Request handler for JSON-RPC 2 over HTTP
method
is ignoredparams
must be a JSON object (not an array) and is passed as keyword arguments to the handler method- the handler method's result is returned as JSON-RPC
result
and wrapped in the JSON-RPC Response
Sucessful request:
--> {"jsonrpc": "2.0",
"method": "call",
"params": {"context": {},
"arg1": "val1" },
"id": null}
<-- {"jsonrpc": "2.0",
"result": { "res1": "val1" },
"id": null}
Request producing a error:
--> {"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)[source]
Response object passed through controller route chain.
In addition to the werkzeug.wrappers.Response
parameters, this
class's constructor can take the following additional parameters
for QWeb Lazy Rendering.
- template (basestring) -- template to render
- qcontext (dict) -- Rendering context to use
- uid (int) -- User id to use for the ir.ui.view render call,
None
to use the request's user (the default)
these attributes are available as parameters on the Response object and can be altered at any time before rendering
Also exposes all the attributes and methods of
werkzeug.wrappers.Response
.
render()[source]
Renders the Response's template, returns the result
flatten()[source]
Forces the rendering of the response's template, sets the result
as response body and unsets template
控制器(Controllers)
控制器需要提供扩展性, 很像模型( Model
), 但是不使用相同的机制,
因为其先决条件 (一个载入模块的数据库) 可能并没有准备好 (比如没有创建数据库, 或者没有选择数据库).
因此控制器提供了他们自己的扩展机制, 与模型(model)的是分开的:
控制器是通过继承( inheriting )
class odoo.http.Controller[source]
来创建的, 并且定义了方法, 这个方法被如下函数装饰 route()
:
class MyController(odoo.http.Controller):
@route('/some_url', auth='public')
def handler(self):
return stuff()
为了 复写(override) 一个控制器, 继承( inherit ) 它的类并且复写相关的方法, 如果需要的话, 使他们重新曝光:
class Extension(MyController):
@route()
def handler(self):
do_before()
return super(Extension, self).handler()
- 用
route()
装饰, 这对于保证这个方法(和路由)可见是必须的: 如果这个方法重新定义时没有被装饰, 它就会成为"未发布的(unpublished)" 所有方法的装饰器是链接的, 如果复写方法的装饰器没有参数, 所有之前的参数会被保留, 任何提供的参数会覆盖之前已经定义的参数, 例如:
class Restrict(MyController): @route(auth='user') def handler(self): return super(Restrict, self).handler()
会改变
/some_url
的认证, 从公共变成用户(需要登录)