Reputation:
I need to download files in zip format. I wrote code that for some reason does not work. I'm trying to do it with controller
from odoo import api, fields, models, _
from odoo.odoo.exceptions import UserError
class IrAttachment(models.Model):
_inherit = ["ir.attachment", "sale.order.line"]
def download_product_attachments(self):
attachment_id = self.datas
if attachment_id:
return {"type": "ir.actions.act_url",
"url": "/download_attachments?attachment_id={}".format(
",".join([str(elem) for elem in attachment_id.ids])),
"target": "new",
"res_id": self.id,
}
else:
raise UserError("Photos were not found")
contriller/main.py
class DownloadZipFile(http.Controller):
@http.route("/download_attachments", type="http", auth="user", website=True)
def download_attachments_product_routes(self, **data):
"""Method compose data with attachments and send for download."""
attachments_ids = [int(x) for x in data["attachment_id"].split(',')]
attachments_items = request.env["ir.attachment"].search([("id", "in", attachments_ids)])
in_memory = BytesIO()
zip_archive = ZipFile(in_memory, "w")
for attachment in attachments_items:
zip_archive.writestr(attachment.filename, base64.b64decode(attachment.image))
zip_archive.close()
res = http.send_file(in_memory, filename="attachments.zip", as_attachment=True)
return res
When I try to go to the /download_attachments. I get an error File "/home/user/PycharmProjects/Odoo14/custom/first_model/controllers/main.py", line 32, in download_attachments_product_routes attachments_ids = [int(x) for x in data["attachment_id"].split(',')] KeyError: 'attachment_id'
What's wrong with me?
Upvotes: 0
Views: 1199
Reputation:
I found a solution to my question.
sale.py
class SaleOrder(models.Model):
_inherit = "sale.order"
attachment = fields.Many2one('ir.attachment')
def download_product_attachments(self):
return {"type": "ir.actions.act_url",
"url": "/download_attachments?res_id={}".format(self.id),
}
controllers/main.py
class DownloadZipFile(http.Controller):
@http.route("/download_attachments/", type="http", auth="user", website=True)
def download_attachments_product_routes(self, **data):
"""Method compose data with attachments and send for download."""
attachments_items = request.env["ir.attachment"].search(
[("res_id", "=", data.get('res_id')), ('res_model', '=', 'sale.order')])
in_memory = BytesIO()
zip_archive = ZipFile(in_memory, "w")
for attachment in attachments_items:
zip_archive.writestr(attachment.name, base64.b64decode(attachment.datas))
zip_archive.close()
res = http.send_file(in_memory, filename="attachments.zip", as_attachment=True)
return res
sale.xml
<record id="view_order_form_inherit" model="ir.ui.view">
<field name="name">sale.order.form</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="//header" position="inside">
<button name="download_product_attachments" type="object" string="Download all files"/>
</xpath>
</field>
</record>
Upvotes: 1