突然有个需求说需要编写一个上传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 requestsclass 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/filebasesixpdf_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_dispositionpdfhttpheaders = [('Content-Type', 'application/pdf')]return request.make_response(filecontent, headers=pdfhttpheaders)else:return request.not_found()return