1. 很多人還是習慣使用restful格式進行接口操作,但odoo已默認jsonrpc,所以需要專門寫一個裝飾器
def json_response(func): """返回去除封裝的JSON""" @wraps(func) def decorate(*args, **kwargs): request.__raw_json = True if hasattr(request, 'jsonrequest'): kwargs.update(request.jsonrequest) ret = func(*args, **kwargs) mime = 'application/json' body = json.dumps(ret, ensure_ascii=False, sort_keys=True) resp = Response( body, status=200, headers=[('Content-Type', mime), ('Content-Length', len(body)), ('Access-Control-Allow-Origin', '*')] ) return resp return decorate
# 在最外層加即可,不出意外,最內層也可,反正自由調位置吧! @json_response @http.route(['/api/post/erp/productcenter/sync'], type='json', auth='public', website=True, csrf=False, cors="*", methods=['POST']) def sync_product_info(self, **params):
2. 若接口使用者使用接口不頻繁,完全無必要設session,因為odoo的session默認為一周;若數據保密性強,應每次訪問都進行登錄。
from odoo.addons.web.controllers.main import ensure_db ensure_db() uid = request.session.authenticate(request.session.db, str(params.get('user')), str(params.get('password'))) # ensure_db() 保證有僅一個數據庫 # request.session.db 返回數據庫名字 # str(params.get('user')) 獲取user值,視情況從不同位置獲取,此為post請求,最終把全代碼貼上 # uid 從數據庫查找到賬號密碼所對的用戶id,是一個id值,有2個目的:1檢驗是否登錄成功,若密碼賬號錯誤,則uid為false 2因為調接口的用戶不一定擁有查看某個表的權限,所以此uid可以作為賦予權限使用 product_count = request.env['xxx.product.center.update.interface'].sudo(uid).search_count([])
3.接口最好考慮到各種報錯,所以進行報錯收集
4.參數解析
.@http.route(['/api/erp/productcenter/count'], type='http', auth='public', website=True, cors="*") # cors="*" 防跨域 # ['/api/erp/productcenter/count'] path不包括端口和ip # type='http' 分http和json等 # auth='public' 分none,user,auth,user只需能登錄就算數
5.代碼參考,多多交流
# -*- coding: utf-8 -*- import json import logging from odoo import http, _ from functools import wraps from odoo.http import request, Response from odoo.addons.web.controllers.main import ensure_db _logger = logging.getLogger(__name__) def json_response(func): """返回去除封裝的JSON""" @wraps(func) def decorate(*args, **kwargs): request.__raw_json = True if hasattr(request, 'jsonrequest'): kwargs.update(request.jsonrequest) ret = func(*args, **kwargs) mime = 'application/json' body = json.dumps(ret, ensure_ascii=False, sort_keys=True) resp = Response( body, status=200, headers=[('Content-Type', mime), ('Content-Length', len(body)), ('Access-Control-Allow-Origin', '*')] ) return resp return decorate class xxxProductCenterAPI(http.Controller): @json_response @http.route(['/api/post/erp/productcenter/sync'], type='json', auth='public', website=True, csrf=False, cors="*", methods=['POST']) def sync_product_info(self, **params): """ 產品中心產品數據同步接口 :param start_num: 要查找的數據起始條碼 :param end_num: 要查找的數據終止條碼 :return: 接口返回值 """ ensure_db() uid = request.session.authenticate(request.session.db, str(params.get('user')), str(params.get('password'))) if uid: try: start_num = params.get('start_num', 0) end_num = params.get('end_num', 1000) product_count = request.env['xxxproduct.center.update.interface'].sudo(uid).search_count([]) if int(start_num) < int(end_num) and product_count > start_num: product_objs = request.env['xxx.product.center.update.interface'].sudo(uid).search([], limit=min(1000, end_num - start_num), offset=start_num, order='id DESC') product_obj_list = [] for product_obj in product_objs: data = { 'operatorType': product_obj.operatorType } product_obj_list.append(data) code = 0 msg = '已返回%s條數據!'%len(product_obj_list) result = product_obj_list else: code = -2 msg = '起始或終止頁碼輸入有誤!' result = '' except Exception, e: code = -3 msg = list(e)[0] result = '' response = { 'code': code, 'msg': msg, 'result': result } else: response = { 'code': 404, 'msg': '用戶名或密碼錯誤', 'result': '' } return response @http.route(['/api/erp/productcenter/count'], type='http', auth='public', website=True, cors="*") def product_count(self): # 返回總數據量 product_count = request.env['xxx.product.center.update.interface'].sudo().search_count([]) response = { 'code': 0, 'result': product_count } return json.dumps(response)