说明
在odoo中,附件存在本地服务器中,由odoo自己做处理,也提供了附件url用于扩展外部存储服务器。本文是用odoo对接阿里云的oss。
代码
odoo在上传文件时,附件字段通常使用挂件(many2many_binary)进行附件上传,会调用http接口,往附件模型里创建一条数据,其中vals[‘datas’]就是base64编码过后的字节数据,我们需要做的就是,把这个字节流数据,上传至oss.
准备
下载oss2模块, 这是阿里云提供的python版本的sdk
pip install oss2
继承修改附件模型的create方法
@api.model
def create(self, vals):
# 重写create方法,在这里上传附件到OSS并更新记录
if 'datas' in vals and isinstance(vals['datas'], bytes):
# 上传文件至OSS并更新URL字段
vals = self._check_contents(vals)
vals.update(self._get_datas_related_values(
base64.b64decode(vals['datas'] or b''),
vals['mimetype']
))
url = self.store_attachment_on_oss(vals['name'], base64.decodebytes(vals['datas']))
vals['url'] = url
del vals['datas']
return super(IrAttachment, self).create(vals)
因为odoo在调用附件的创建方法时,对数据进行了编码操作,oss上传的数据,要求不能编码,所以需要进行解码。
编写上传oss方法
def store_attachment_on_oss(self, name, file_content, access_token=None):
# 获取Odoo配置中的OSS相关信息
access_key_id = config.get('access_key')
access_key_secret = config.get('access_secret')
bucket_name = config.get('bucket')
endpoint = config.get('endpoint')
auth = oss2.Auth(access_key_id, access_key_secret)
name_list = name.split('.')
suffix = name_list[-1]
new_name = f'{name_list[0]}-{fields.Datetime.now()}.{suffix}'
endpoint = f'{endpoint}/{suffix}'
bucket = oss2.Bucket(auth, endpoint, bucket_name)
try:
# 上传文件到OSS
dis = f'attachment'
result = bucket.put_object(new_name, file_content, headers={'Content-Disposition': dis})
# 返回存储后的URL
return result.resp.response.url
except Exception as e:
raise UserError(_("文件上传至OSS失败: %s") % str(e))
上述的配置,都写入到odoo.conf文件里,参数怎么获取,可以查阅阿里云oss,
调用put_object上传至oss。完成对接