【转载】odoo技术开发白皮书 第二部分 第三章 控制器

转载:http://book.odoomommy.com/chapter2/README3.html

第三章 控制器

控制器(controller)是处理页面请求的处理器,通常的http和json请求都是由controller负责处理和转发的,odoo默认缺省的方式是http。 odoo内置的web服务器werkzeug跟Python著名的web框架Flask用的是同一个,因此,你在定义路由的时候会发现跟Flask的定义方式十分相像。

路由的定义

先来看一个web路由的栗子:

@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。

获取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)

获取POST方法的数据

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

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

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

下面是一个例子:

<form class="oe_login_form" role="form" t-attf-action="/baybao_faceid/register/" method="post" enctype="multipart/form-data" onsubmit="this.action = this.action + location.hash">
                    <input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
                    <div class="form-group field-community">
                        <input type="file" name="img" />
                    </div>
</form>

后端的接收代码:

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

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

获取JSON数据

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

data = request.jsonrequest.data

在controller中调用model对象

在controller中引用model对象的方法跟model中的方法类似:

request.env["sale.order"]

导出Excel的例子

controler不仅可以处理日常的请求,也可以返回一个文件,这里以Excel文件为例:

wkbook = xlwt.Workbook()
    for name in names:
        order = request.env["sale.order"].sudo().search(
            [('name', '=', name)], limit=1)
        if order:
            wksheet = wkbook.add_sheet(f"销售订单{order.name}")

            wksheet.write(0, 0, "产品")
            wksheet.write(0, 1, "订购数量")
            wksheet.write(0, 2, "计量单位")
            wksheet.write(0, 3, "单价")
            wksheet.write(0, 4, "小计")

            row = 1
            for line in order.order_line:
                wksheet.write(row, 0, line.product_id.name)
                wksheet.write(row, 1, line.product_uom_qty)
                wksheet.write(row, 2, line.product_uom.name)
                wksheet.write(row, 3, line.price_unit)
                wksheet.write(row, 4, line.price_subtotal)
                row += 1

    buffer = BytesIO()
    wkbook.save(buffer)
    data = buffer.getvalue()

    headers = [
        ('Content-Type', 'application/vnd.ms-excel'),
        ('Content-Length', len(data)),
        ('Content-Disposition', 'attachment; filename="sale.order.xls"')
    ]
    return request.make_response(data,
                                         headers=headers)

获取用户的访问IP

odoo虽然用的是同flask一样的werkzeug,但是获取用户的ip却不想flask那么简单,在flask中获取用户访问ip可以直接使用

request.remote_addr

而在odoo中要复杂一些,获取用户的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']

返回404

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

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

返回 500

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

跳转其他网址

@http.route('/book_store/redirect_to_baidu/', auth='public')
def object(self,**kw):
    return werkzeug.utils.redirect("http://www.baidu.com", code=301)

redirect方法接受两个参数,第一个code指明要跳转的URL,相对路径,如果要跳转站外路径需要补全路径。code指明条状状态是301还是302,默认是302跳转。

也可以在request中直接调用redirect方法:

request.redirect("http://www.baidu.com")

Http Response

一般情况下,我们返回给前端的对象都是HttpResponse,odoo已经帮我们封装好了一个make_response方法,在controller中直接返回即可。

return request.make_response(content_base64, headers)

第一个参数为返回的数据对象,第二个参数为headers。

Json Response

如果要返回Json对象,我们不需要封装,直接返回dict对象即可。由于odoo使用的是jsonrpc,这里返回的结果会被自动包裹在

{
    "jsonrpc":"2.0",
    "id":null,
    "result":"result"
}

的result中。

提示警告信息

警告信息通常用于提示用户缺少必要的输入条件或者当前环境不符合要求,我们可以通过在controller中返回一个包含waring的字典值来完成这个动作:

return {'warning': _('No picking or location corresponding to barcode %(barcode)s') % {'barcode': barcode}}

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设置为一致。

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《Odoo开发手册第五版》是一本介绍Odoo开发的指南和参考书籍。该书的出版旨在帮助读者了解Odoo的开发流程和技术要点,并提供实际的开发案例和示例代码。本书内容详尽,以通俗易懂的语言解释Odoo的开发概念和技术细节,适合初学者和有一定Odoo开发经验的开发者。 这本手册第五版按照Odoo 13版本进行了更新,并涵盖了Odoo开发的一系列主题,包括模型定义、视图设计、业务逻辑编写、报表生成、安全权限管理以及模块集成等等。读者将通过本书了解到如何使用Odoo开发框架进行模块的创建和定制,以及如何设计和实现功能丰富的Odoo应用。 《Odoo开发手册第五版》以实战为主线,并伴随着大量的实例代码和案例分析,帮助读者掌握Odoo开发的实际操作技巧。此外,该书还提供了常见问题解答和开发技巧分享,可以帮助读者更好地理解和应用Odoo开发技术。 总的来说,《Odoo开发手册第五版》是一本权威而实用的指南,它通过详细的解释和实例演示,全面介绍了Odoo开发的方方面面。读者可以通过阅读本书快速掌握Odoo的开发技术,从而开发出高质量和可扩展的Odoo应用。无论是初学者还是有经验的开发者,都能够从中受益,并在实际项目中灵活应用Odoo的开发能力。 ### 回答2: odoo是一款开源的企业管理软件,提供了一套全面的解决方案,涵盖了销售、采购、库存管理、人力资源、财务等多个业务模块。odoo开发手册第五版是针对odoo软件开发的指南,旨在帮助开发人员了解和掌握odoo开发的技术和方法。 该手册涵盖了odoo开发的基本知识,如模型、视图、控制器、过程、报表等,以及odoo开发常用的工具和技术,如模块创建、对象关系映射、数据迁移、安全等。手册还详细介绍了odoo的架构和代码结构,以及开发过程中常见的问题和解决方案。 通过学习该手册,开发人员可以了解odoo的整体架构和设计,理解odoo开发的基本原理和方法,掌握odoo开发的常用工具和技术,提高开发效率和质量。此外,手册还提供了丰富的示例代码和实践案例,帮助开发人员理解和应用所学知识。 总之,odoo开发手册第五版是一本权威的指南,为odoo软件开发提供了全面的技术支持和实践指导。通过学习和运用该手册,开发人员能够更好地开发和定制odoo系统,满足企业的个性化需求,提升企业的管理效率和竞争力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值