odoo16 上传/下载 文件接口的实现

突然有个需求说需要编写一个上传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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值