Odoo_控制器(controller)常用知识点

发布时间 2023-12-03 22:25:38作者: 手可摘星辰。

1.路由的定义

@http.route([
        '/report/<converter>/<reportname>',
        '/report/<converter>/<reportname>/<docids>',
    ], type='http', auth='user', website=True)
def report_routes(self, reportname, docids=None, converter=None, **data):
    report = request.env['ir.actions.report']._get_report_from_name(reportname)

http.route装饰器的参数:

  • type: 指定请求的方式,可选值http和json
  • auth: 认证方式,user,public,none 其中public和none指明用户不需要登录即可访问改URL。
  • website: 是否是网站的URL。

2.获取GET请求的参数

controller获取GET方法传进来的参数,使用reqest.params:

signature = request.params.get("signature",None)
timestamp = request.params.get("timestamp",None)
echostr = request.params.get("echostr",None)
nonce = request.params.get("nonce",None)

3.获取POST请求的数据

controller获取POST方法传进来的原始参数,使用request.httprequest.data:

request.httprequest.data.decode("utf-8")

对于图片等二进制文件,需要在前段form表单中添加属性enctype="multipart/form-data",然后在controller中使用request.httprequest.files属性获取文件。

img1 = request.httprequest.files.get('img')
...
"idnoimg1": b64encode(img1.read())

由于odoo存储二进制的方式为base64编码,因此,我们在拿到二进制文件以后需要使用base64编码存储到系统中。

4.获取JSON数据

当API接口使用json方式传输数据时,controller中获取json数据的方式为:

data = request.jsonrequest.data

5.获取用户的访问ip

获取用户的IP代码如下:

request.httprequest.environ['REMOTE_ADDR']

对于前端挂在了nignx的服务器,Nignx需要配置为转发用户的真实IP:

proxy_set_header Host $host:80;
proxy_set_header Origin "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

然后在odoo中获取nginx的真实IP:

request.httprequest.environ['HTTP_X_REAL_IP']

6.返回404

controller的web服务器用的是werkzeug,因此像redirect、404等返回对象,我们可以利用werkzeug提供的功能来实现。

@http.route('/book_store/raise_404/', auth='public')
def index(self, **kw):
    return werkzeug.exceptions.NotFound()

7.返回500

@http.route('/book_store/raise_500/', auth='public')
def list(self, **kw):
    return werkzeug.exceptions.InternalServerError()

8.跳转其他网摘

    @http.route(_checkout_return_url, type='http', auth='public', csrf=False)
    def stripe_return_from_checkout(self, **data):

        return request.redirect('/payment/status')

9.controller的继承与重载

如果想要对已有的controller进行覆盖,可以通过指定模块路径的方式来实现。

例如,我们现有一个controller

class DeliveryKdn(http.Controller):
@http.route('/delivery_kdn/eorder', auth='public')
def index(picking, id, **kw):

    picking = request.env["stock.picking"].browse(int(id))
    if not picking:
        return

    res = picking._create_eorder(
        picking.partner_id, picking.env.user.partner_id)

    if not res['Success']:
        return request.make_response(f"打印电子面单失败:{res['Reason']}")

    return request.make_response(res['PrintTemplate'])

现在,我们想要对这个controler的代码进行重构,根据不要动既有模块代码的原则,我们新建了一个模块,并继承该模块的controller。

from odoo.addons.delivery_kdniao.controllers.controllers import DeliveryKdn

class controller(DeliveryKdn):

    @http.route('/delivery_kdn/eorder', auth='public')
    def index(picking, id, **kw):
        pass

其实原理是利用的python自带的的子类继承父类,并将覆盖掉父类同名方法的特性。另外,这里需要将两个route的URL设置为一致。

10.参考文献

第三章 控制器 · odoo技术开发白皮书 (odoomommy.com)