ODOO13 开发教程九 WEB控制器及接口请求

本文详细介绍了ODOO13中的控制器(Controller)如何作为后台与前端数据交互的桥梁,包括route参数、methods参数和type参数的使用。通过实例展示了如何创建动态路由、处理不同HTTP方法以及JSON类型的接口请求。同时强调了参数设置的重要性,如auth、methods和cors,以及在控制器方法中获取和使用请求参数的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

controller

ODOO中的控制器Controller,和其他框架中的控制器(有些称为路由/接口,具体看具体拿它来做什么)作为后台和前段数据交互的桥梁。但他和其他框架中的控制器又有些不一样的地方,就是在某些参数控制下,如果没有创建数据库,或者在多数据库却没有指定数据库时,控制器是不可用的。

ODOO中的控制器,也具有拓展性,控制器通过继承Controller进行创建,就像ODOO中的模型需要继承Model创建。控制器方法通过route()装饰器与路由关联,route作为修饰控制器的装饰器,它采用路由字符串和许多属性来自定义其行为或安全性。

from odoo import http

class MainControllers(http.Controller):

    @http.route('/hello', auth='public', website=True)
    def print_hello_world(self):
        return '<h1>Hello, World!</h1>'

上面的例子是最简单的实现,在新的页签访问http://localhost:8069/hello,会看到 Hello, World!

route 装饰器的参数及意义如下:

  • route – 字符串或字符串列表。决定哪种http请求匹配所装饰方法的路由部分。可以是单个字符串或字符串列表。
  • type – 请求的类型,可为'http' 或 'json'.
  • auth – 认证方法的类型,可为以下类型:
    • user: 用户必须认证且当前请求将使用用户的权限进行执行。
    • public: 用户可认证也可不认证。如未认证,当前请求会使用共享Public用户进行执行。
    • none: 即使用没有数据库,方法也一直是活跃的。主要由框架和认证模块使用。它们的请求代码对访问数据库没有任何作用,也没有表明当前数据库或当前用户的配置。
  • methods – 一个这个路由所应用的http方法的列表。如未指定,允许使用所有方法,常用的请求方式有GET、POST。
  • cors – Access-Control-Allow-Origin cors 指令值,主要用来控制解决跨域问题。
  • csrf (bool) – 是否应为路由启用CSRF保护。默认为 True

 route 参数

像上面最简单的例子,它的route参数是完全匹配URL的。另外,路由字符串也可以使用转换器模式来匹配URL,并使这些位作为本地变量可用。例如,我们可以创建一个新的控制器方法,它接受一个动态的参数,并将此参数作为本地变量输出:

    ... ...

    @http.route('/hello/<name>', auth='public', website=True)
    def print_hello_name(self, name):
        return '<h1>Hello, {}!</h1>'.format(name)

在新的页签访问http://localhost:8069/hello/ZERONE,会看到 Hello, ZERONE!注意看控制器方法,它额外接收了一个name参数。可以直接作为变量使用,参数还可以使用另一种方式接收(看下面的例子),使用可变参数。但这么做的前提是修饰起中的 type 参数应为 http。上面的例子中,没有书写此参数,因为此参数默认为 http 。

    ... ...

    @http.route('/hello/<name>/<greetings>', auth='public', website=True)
    def print_greetings(self, **kw):
        return '<h1>Hello, {}! {} !</h1>'.format(kw.get("name"),kw.get("greetings"))

在新的页签访问http://localhost:8069/hello/ZERONE/傍晚好!,会看到 Hello, ZERONE!傍晚好! 在这个例子中,使用可变参数也能获取并做为变量使用。写到这里,还要说一下,在同一个class中,不要书写相同的控制器名称,即使URLs相同也不行。还有一点,接收的参数名需要和URLs里占位符的参数名相同。

Odoo还额外提供了一个的转换器,称为model,它可以在给定id时直接提供记录。让我们在zerone.book模型中增加一条name为 来学ODOO13吧 的新记录,并记下它的id(假如新建记录的id=1),然后增加如下代码:

    ... ...

    @http.route('/find/book/<model("zerone.book"):book>/', auth='public', website=True)
    def find_a_book_by_id(self, book):
        return book.name

在新的页签访问http://localhost:8069/find/book/1/,会看到页面输出 来学ODOO13吧 。在这个例子中,我们在route参数中,使用<model("zerone.book"):book>指定了模型为 zerone.book,它也代表了我们传入的参数id,并把zerone.book 模型中,id 为1 的记录用 book 来表示。


methods 参数

上面的例子,都是默认使用 type = http 的控制器,当 type = http 的时候,可以使用 methods 参数控制请求方式。在最上面的参数说明中有提到:如果不显示的限制请求方式,这将允许所有的请求方式。

    ... ...

    @http.route('/book_list', type="http", auth='public', website=True, cors='*', csrf=False)
    def book_list(self, **kw):
        print(kw)
        book_obj = http.request.env['zerone.book']
        books = book_obj.sudo().search([], order='id desc')
        book_lst = []
        for book in books:
            book_lst.append({"id":book.id,"name":book.name})
        return json.dumps({"book_lst":book_lst})

除了在通过控制器方法中的固定参数、动态参数(**kw)接收请求参数外,还可以在控制器方法中不使用任何形式的参数,把参数解析放到控制器方法体中,使用 http.request.httprequest.args 获取参数,就像下面这样:

    ... ...

    @http.route('/book_list', type="http", auth='public', website=True, cors='*', csrf=False)
    def book_list(self):
        kw = http.request.httprequest.args
        print(kw.get("a"))
        book_obj = http.request.env['zerone.book']
        books = book_obj.sudo().search([], order='id desc')
        book_lst = []
        for book in books:
            book_lst.append({"id":book.id,"name":book.name})
        return json.dumps({"book_lst":book_lst})

 我们可以通过GET方式请求上面的接口(在浏览器直接请求就可见效果),也可以使用POST方式请求此借口,下面使用PostMan或者其他工具演示例子(使用工具测试,可能会引起跨域问题,和csrf安全保护问题,所以在修饰起里需要加上csrf = False 和 cors = "*")。在做请求时,你需要按下面的操作,保证你的借口可被访问到:

  • 你需要将你的控制器所在模块,配置到config文件的server_wide_modules参数中
  • 如果你有多个数据库,你需要将要测试的数据库名,配置到config文件的dbfilter参数中

就像这样

 
[options]
 
db_host = localhost
db_port = 5432
... ...
server_wide_modules = web,zerone_inherit
dbfilter = ^db_demo$

配置好上面两条后,可以进行请求测试了,先使用GET方式请求:

再使用POST方式请求:

通过了上面两个借口测试,现在试着通过增加 methods = ["GET"] 控制只允许GET请求,并通过POST方式请求此借口:

    @http.route('/book_list/get', type="http", methods=["GET"], auth='public', website=True, cors='*', csrf=False)
    def book_list_only_get(self, **kw):
        print(kw)
        book_obj = http.request.env['zerone.book']
        books = book_obj.sudo().search([], order='id desc')
        book_lst = []
        for book in books:
            book_lst.append({"id":book.id,"name":book.name})
        return json.dumps({"book_lst":book_lst})

我们将得到如下信息,请求方式不允许:

通过增加 methods = ["POST"] 控制只允许POST请求,并通过GET方式请求此借口:

    @http.route('/book_list/post', type="http", methods=["POST"], auth='public', website=True, cors='*', csrf=False)
    def book_list_only_post(self, **kw):
        print(kw)
        book_obj = http.request.env['zerone.book']
        books = book_obj.sudo().search([], order='id desc')
        book_lst = []
        for book in books:
            book_lst.append({"id":book.id,"name":book.name})
        return json.dumps({"book_lst":book_lst})

同样的,我们也将得到如下信息,请求方式不允许:

以上就是在 type = http 时,使用 methods 参数的作用。


type 参数

上面的例子都是请求类型(type)为 http 的控制器,除了http,还有一种类型为 json。下面将通过例子说明 json 类型的控制器的书写方式。

像下面这样,使用 type="json" ,在控制器方法体中使用 http.request.jsonrequest 来获取参数(注意使用json时,方法参数使用固定参数和动态参数,是获取不到数据的):

    ... ...
    
    @http.route('/book_list/json', type="json", auth='public', website=True, cors='*', csrf=False)
    def book_list_json(self):
        kw = http.request.jsonrequest
        print(kw)
        book_obj = http.request.env['zerone.book']
        books = book_obj.sudo().search([], order='id desc')
        book_lst = []
        for book in books:
            book_lst.append({"id":book.id,"name":book.name})
        return {"book_lst":book_lst}

可以看到,json类型的路由返回值是有固定格式的,控制器返回的结果被作为result的值封装起来。如果你是用json类型的请求,发现返回值多了这么个结构,不要惊讶,也别想着怎么去改它,你能做的就是适应它。感兴趣可以学习一下 json-rpc。


接口调试,由基友LiuC来补充,等待更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值