突然有个需求说需要编写一个上传pdf 接口
首先需要准备如下 xx.xx模型 module 部分 如下:
attachment_count = fields.Integer(compute='_compute_attachment_count', string='附件数量', required=True)
def _compute_attachment_count(self):
# 附件数量计算
attachment_data = self.env['ir.attachment'].read_group(
[('res_model', '=', 'xx.xx.你的模型'), ('res_id', 'in', self.ids)], ['res_id'], ['res_id'])
attachment = dict((data['res_id'], data['res_id_count']) for data in attachment_data)
for expense in self:
expense.attachment_count = attachment.get(expense.id, 0)
def attachment_image_preview(self):
"""附件上传"""
self.ensure_one()
# domain可以过滤指定的附件类型 (mimetype)
domain = [('res_model', '=', self._name), ('res_id', '=', self.id)]
return {
'domain': domain,
'res_model': 'ir.attachment',
'name': u'附件管理',
'type': 'ir.actions.act_window',
'view_id': False,
'view_mode': 'kanban,tree,form',
'view_type': 'form',
'limit': 20,
'context': "{'default_res_model': '%s','default_res_id': %d}" % (self._name, self.id)
}
view部分 代码如下
<sheet>
<div class="oe_button_box" name="button_box">
<button name="attachment_image_preview" type="object" class="oe_stat_button" icon="fa-image">
<div class="o_stat_info">
<span class="o_stat_text">附件管理</span>
<field name="attachment_count"/>
</div>
</button>
</div>
......
</sheet>
效果如下
好了前期准备完成了 接下来看接口如何实现的
上传接口:
# -*- coding: utf-8 -*-
from odoo import http
import json
from odoo.http import request, Response
import base64
import requests
class pdf_upload_Request(http.Controller):
error = "系统错误"
# pdf上传接口
@http.route("/xx/pdf/upload", type='http', auth="public", csrf=False, method=['POST'], website=True, cors="*")
def pdf_upload(self, **params):
print("--pdf上传")
id = params.get('id', None) # 订单抬头id 必输项
filename = params.get('filename', None) # 文件名称 必输项
if id is None:
back_data = {'code': 300, 'msg': 'id没传入'}
return (json.dumps(back_data))
if filename is None:
back_data = {'code': 300, 'msg': '文件名称为空'}
return (json.dumps(back_data))
try:
id = 1 # 订单抬头id 必输项 我现在给他写死为了测试
filename = "测试" # pdf 文件名称
# pdf_base 文档base64 必须是base64位!!!!!!!
#测试阶段你可以去自动生成一个测试 https://www.lddgo.net/convert/filebasesix
pdf_base = "JVBERi0xLjMNCiXi48/=="#这个必须是base64!!!!
Model = request.env['ir.attachment']
attachment = Model.sudo().create({
'name': filename,
'datas': pdf_base, #
'res_model': 'xx.xx.你的模型', # 你的model,
'res_id': int(id)
})
back_data = {'code': 100, 'msg': '上传成功'}
return (json.dumps(back_data))
except Exception as e:
back_data = {'code': 300, 'msg': '上传失败', 'error': str(e)}
return (json.dumps(back_data))
下载接口:(我写了两种自己查看哪个符合自己)
第一种方式:
@http.route("/xx/pdf/download", type='http', auth="public", csrf=False, method=['GET'],website=True, cors="*")
def pdf_download(self, model='ir.attachment',filename_field='name',mimetype=None, **params):
print("pdf下载")
filename = params.get('filename', None) # 文件名称 必输项
print("filename==",filename)
# 第一种实现方式
# filename = "文件名称"
record_id = request.env['ir.attachment'].sudo().search([('name', '=', filename),('res_model','=','xx.xx.你的模型')])
if record_id:
# print("找到了")
stream = request.env['ir.binary']._get_stream_from(record_id, 'datas', 'None', filename_field, mimetype)
send_file_kwargs = {'as_attachment': False}
return stream.get_response(**send_file_kwargs)
else:
back_data = {'code': 300, 'msg': '没找到相关文件名称'}
return (json.dumps(back_data))
我用postamn请求效果如下
第二种方式:
# pdf 下载接口
@http.route("/xx/pdf/download", type='http', auth="public", csrf=False, method=['GET'],
website=True, cors="*")
def pdf_download(self, model='ir.attachment', filename_field='name', mimetype=None, **params):
# 第二种实现方式
filename = "上传文件名称"
record_id = request.env['ir.attachment'].sudo().search([('name', '=', filename),('res_model','=','xx.xx.你的模型')])
attachment = request.env['ir.attachment'].sudo().search_read(
[('id', '=', int(record_id.id))],
["name", "datas", "res_model", "res_id", "type", "url"]
)
if attachment:
attachment = attachment[0]
else:
return redirect('/xx/pdf/download')
res_id = attachment['res_id']
if attachment["type"] == "url":
if attachment["url"]:
return redirect(attachment["url"])
else:
return request.not_found()
elif attachment["datas"]:
# print("attachment===",attachment["datas"])
filecontent = base64.b64decode(attachment["datas"])
from odoo.http import content_disposition
pdfhttpheaders = [('Content-Type', 'application/pdf')]
return request.make_response(filecontent, headers=pdfhttpheaders)
else:
return request.not_found()
return