view 视图中下载按钮的编辑 <record id=“action_download_zip” model=“ir.actions.server”> <field name=“name”>附件打包下载</field> <field name=“model_id” ref=“model_activity_event”/> <field name=“binding_model_id” ref=“model_activity_event”/> <field name=“state”>code</field> <field name=“code”> if records: action = { ’name’: ‘Visit Webpage’, ’type’: ‘ir.actions.act_url’, ‘url’: ‘/document/zip/’+str(records.download_zip()), ’target’: ‘self’, } </field> </record>model 中获取需要下载的文件的ID,并返回字符串集合打包下载的方法@api.multidef download_zip(self): dones = self.env[‘ir.attachment’].search([(‘res_model’, ‘=’, ‘activity.event’), (‘res_id’, ‘=’, self.id)]) file_ids = ’’ for x in dones: file_ids = file_ids + str(x.id) + ‘,’ print(file_ids) return { file_ids }controller.py中的打包下载引用和方法,如下代码# -- coding: utf-8 --import base64import ioimport jinja2import jsonimport loggingimport osimport sysimport zipfileimport timeimport werkzeugimport werkzeug.exceptionsimport werkzeug.utilsimport werkzeug.wrappersimport werkzeug.wsgifrom odoo import httpfrom odoo.http import content_disposition, dispatch_rpc, request, \ serialize_exception as serialize_exception, Responsefrom odoo.exceptions import AccessError, UserError, AccessDeniedfrom odoo.models import check_method_namefrom odoo.service import db, security_logger = logging.getLogger(name)if hasattr(sys, ‘frozen’): # When running on compiled windows binary, we don’t have access to package loader. path = os.path.realpath(os.path.join(os.path.dirname(file), ‘..’, ‘views’)) loader = jinja2.FileSystemLoader(path)else: loader = jinja2.PackageLoader(‘odoo.addons.web’, “views”)env = jinja2.Environment(loader=loader, autoescape=True)env.filters[“json”] = json.dumps# 1 week cache for asset bundles as advised by Google Page SpeedBUNDLE_MAXAGE = 60 * 60 * 24 * 7DBNAME_PATTERN = ‘^[a-zA-Z0-9][a-zA-Z0-9.-]+$’#———————————————————-# Odoo Web helpers#———————————————————-db_list = http.db_listdb_monodb = http.db_monodbclass DownloadAll(http.Controller): def _get_file_response(self, id, filename=None, field=‘datas’, share_id=None, share_token=None): """ returns the http response to download one file. """ status, headers, content = request.registry[‘ir.http’].binary_content( id=id, field=field, filename=filename, related_id=share_id, access_token=share_token, access_mode=‘documents_share’, download=True) if status == 304: response = werkzeug.wrappers.Response(status=status, headers=headers) elif status == 301: return werkzeug.utils.redirect(content, code=301) elif status != 200: response = request.not_found() else: content_base64 = base64.b64decode(content) headers.append((‘Content-Length’, len(content_base64))) response = request.make_response(content_base64, headers) return response def _make_zip(self, name, attachments): “““returns zip files for the Document Inspector and the portal. :param name: the name to give to the zip file. :param attachments: files (ir.attachment) to be zipped. :return: a http response to download a zip file. "”” stream = io.BytesIO() try: with zipfile.ZipFile(stream, ‘w’) as doc_zip: for attachment in attachments: if attachment.type in [‘url’, ’empty’]: continue filename = attachment.datas_fname doc_zip.writestr(filename, base64.b64decode(attachment[‘datas’]), compress_type=zipfile.ZIP_DEFLATED) except zipfile.BadZipfile: _logger.exception(“BadZipfile exception”) content = stream.getvalue() headers = [ (‘Content-Type’, ‘zip’), (‘X-Content-Type-Options’, ’nosniff’), (‘Content-Length’, len(content)), (‘Content-Disposition’, content_disposition(name)) ] return request.make_response(content, headers) @http.route([’/document/zip/<string:file_ids>’], type=‘http’, auth=“public”) def _get_zip(self, file_ids=None, *args, **kwargs): “““route to get the zip file of the selection in the document’s Kanban view (Document inspector). :param file_ids: if of the files to zip. :param zip_name: name of the zip file. "”” file_ids = file_ids[2:-3] print(file_ids) timestamp = time.strftime(’%Y%m%d%H%M%S’,time.localtime(time.time())) zip_name = ‘activity-’ + timestamp + ‘.zip’ ids_list = [int(x) for x in file_ids.split(’,’)] print(ids_list) env = request.env return self._make_zip(zip_name, env[‘ir.attachment’].browse(ids_list))