[odoo16] odoo.js concept external api to access data through the controller layer

I saw a video yesterday: It is also feasible to write the web layer separately for the front end, and use odoo for the back end. You can get the front-end data through the controller layer, and add, delete, modify and check the database, which is quite interesting. There is only one case in the video, that is, the front-end vue+axios got a version number information at the bottom of the odoo setting interface: this is it (v14.0 version in the video)

Just because I was free, I wrote an example to test whether the controller layer works well (regardless of login and permission issues)

The video link is as follows: If you are interested, you can watch it yourself

odoojs public class 1 How to connect the front end to odoo_哔哩哔哩_bilibili

Simply write:

1. Test the get request:

# get请求的demo(helloWorld)
class HelloWorld(http.Controller):
    @http.route('/hello_world', type='http', auth='public', website=True, csrf=False)
    # 可接受任何类型的参数  所以使用 **kwargs
    def hello_world(self, **kw):
        response = "Hello, world!"
        return http.Response(response, headers={'Access-Control-Allow-Origin': '*'})

    @http.route('/hello/<string:name>', type='http', auth='public', website=True, csrf=False)
    def hello_name(self, name, **kw):
        response = "Hello, %s!" % name
        return http.Response(response, headers={'Access-Control-Allow-Origin': '*'})

There are two external interfaces written here, one is auth, both are public, the type is http, the first one returns a helloworld, and the other one also adds a name that you set in the data.

 testtwo () {
      axios.get('/api/hello_world')
        .then(response => {
          this.helloWorldMessage = response.data;
        })
        .catch(error => {
          console.log(error);
        });
    },
    testthree () {
      axios.get(`/api/hello/${this.name}`)
        .then(response => {
          this.helloNameMessage2 = response.data;
        })
        .catch(error => {
          console.log(error);
        });
    },

Here, axios is used to send the request, the cross-domain problem has been solved, /api is my odoo service path, so when I send the request, I can directly /api/interface name (basic front-end skills, everyone knows it by default)

 proxyTable: {
      "/api": {
        // target: "https://www.vue-js.com",
        target: "http://192.168.3.92:8069", // 你请求的第三方接口
        changeOrigin: true, //是否改变源地址。
        pathRewrite: {
          // 路径重写,
          "^/api": " " // 替换target中的请求地址,也就是说以后你在请求http://api.jisuapi.com/XXXXX这个地址的时候直接写成/api即可。
        }
      }
    },

Let's take a look at the request response: all 200 requests are successful, and the response data is also rendered on the page. The get request is fine.

 2. Test [Front-end query request->odoo processing request->postsql database query record->return to front-end->render to page]:

# 数据库中检索所有产品的demo接口
class ProductController(http.Controller):
    @http.route('/products', auth='public', type='http', methods=['GET'], csrf=False)
    def get_products(self, **kw):
        products = request.env['product.template'].sudo().search([])
        # 定一个一个数组ps_all
        ps_all = []
        for p in products:
            ps_all.append(p.name)
        # json.dumps(data,指定文字字符,可防止乱码)
        response = json.dumps(ps_all, ensure_ascii=False)
        # return http.request.make_response(products.read(), headers=[('Content-Type', 'application/json')])
        # 使用 make_response方法将它们转换为JSON格式的响应
        return http.request.make_response(response, headers={'Access-Control-Allow-Origin': '*'})

This is to query the product name in the product table. I added three pieces of data:

The data of the product.template table in postsql is as follows: I selected the name field in the table and found three pieces of information

 Just call the processed data directly in the front-end vue, and get the corresponding information:

  testfour () {
      axios.get('/api/products')
        .then(response => {
          this.products = response.data;
          console.log(response);
        })
        .catch(error => {
          console.log(error);
        })
    },

3. Test the post request:

This time we write an interface for adding users and simulating user registration:


class LogonController(http.Controller):
    # 用户注册的接口
    @http.route('/add_user', auth='public', type='json', methods=['POST'], csrf=False, save_session=True)
    def add_user(self, **post):
        # 接受到前端传过来的json数据
        front_data = request.httprequest.data.decode("utf-8")
        # 使用json.loads解析一下json数据(分开写更容易看懂)
        data_dict = json.loads(front_data)
        # 输出解析后的字典数据
        print("字典数据", data_dict)
        # 访问字典中的具体值
        user = data_dict['user']
        pwd = data_dict['pwd']
        print(user)
        print(pwd)
        if not user or not pwd:
            print("post", post)
            print(user)
            print(pwd)
            return {'code': 1, 'msg': '参数不全'}
        # 创建新用户
        try:
            print('进入创建用户这一步')
            new_user = request.env['mydemo.mydemo'].sudo().create({'user': user, 'pwd': pwd})
            return {'code': 0, 'msg': '添加用户成功',
                    'data': {'id': new_user.id, 'user': new_user.user, 'pwd': new_user.pwd}}
        except Exception as e:
            return {'code': 1, 'msg': '添加用户失败:%s' % e}

I customized a module myself, which is quite simple, and the table name is mydemo. The interface logic is to add a piece of data to this table:

from odoo import models, fields, api, http

class mydemo(models.Model):
    _name = 'mydemo.mydemo'
    _description = 'mydemo.mydemo'

    user = fields.Char()
    pwd = fields.Integer()

In the front end, we write two input boxes and one button, click the button and get the content of the input box -> register at the back end -> return a registration success or Erro:

 gologon () {
      // 定义请求参数
      const data = {
        user: 'username',
        pwd: 123
      };
      // 发起post请求
      axios.post('/api/add_user', data,
        { headers: { 'Content-Type': 'application/json', 'charset': 'utf-8' } })
        .then(response => {
          console.log(response.data);
        })
        .catch(error => {
          console.log(error);
        });
      console.log("提交了");
      console.log(this.user);
      console.log(this.pwd);
    }

  },

Take a look at the result: the front end sends a json request ->>> odoo backend

 After the backend is processed, the insert is inserted into the database: overall, there is no problem

In this way, the front-end and back-end of odoo can be separated, so that the front-end programmers can write directly with vue or react, write the form function logic, and then write the logic layer at the back-end of odoo, and then adjust the interface to realize their own ERP. The essence is the stage of removing the dross, fully customized (of course, if the permission problem can be solved, I feel that if auth='user', I will definitely not be able to get the data, otherwise it is too insecure).

To the end: As for someone who must say that odoo clearly provides a view layer, isn't this superfluous? I can only say that xml is quite cumbersome to write, and the grammar is difficult to get started, and the exclusive owl doesn't understand what it means, or vue is easy to write, the above is my humble opinion, don't spray it. I am just a junior front-end QWQ graduate who will graduate in 2022. I have a limited level of QWQ.

Guess you like

Origin blog.csdn.net/ONLYSRY/article/details/129880525