odoo附件
有两种存储方式:
1 以二进制的方式存放在数据库中
2 存放在文件系统中
odoo16 默认存放位置 ~/.local/share/Odoo/filestore
相关数据库表:
ir_attachment
比较重要的字段:
- res_id : 关联表的记录Id
- res_model : 关联模型
- res_field : 关联模型的字段名
- file_size: 文件大小
- store_fname: 如果以文件存储,存储的是文件名 比如: 07/071d2bebb8a1262baec43c2da9a6b9ab7b783671
- db_datas: 如果以db存储,存储的是附件的二进制数据,如果以文件存储,这里为null
一 通过控制器操作附件
1 模板
<div class="item">
<label for="attachment">附件1:</label>
<input type="file" id="attachment" name="attachment" />
</div>
2 控制器
class HxJixiao(http.Controller):
@http.route('/hx_jixiao/feedback', type='http', auth='none', methods=['POST', 'GET'], csrf=False)
def submit_feedback(self, **kwargs):
if request.httprequest.method == "POST":
attachment = kwargs.get('attachment')
attachment_data = attachment and attachment.read() or None
attachment_data = base64.b64encode(attachment_data) if attachment_data else None
feedback = request.env['hx.jixiao.fankui'].sudo().create({
'name': kwargs.get('name'),
'content': kwargs.get('content'),
'user_name': kwargs.get('user_name'),
'attachment': attachment_data if attachment_data else None,
'attachment_fname': attachment.filename if attachment else "",
})
#return request.make_response('谢谢您的反馈!')
return request.render('hx_jixiao.feedback_thanks')
else:
return request.render('hx_jixiao.feedback_form')
注意:
1 attachment = kwargs.get(‘attachment’) 获取到的是一个对象, 不能直接存储, 通过read()方法转成字节码,然后再通过base64编码
2 attachment.filename 可用获取到文件名,可用保存到数据库中
3 后台显示
form视图中要这样写,这样会显示文件名,否则显示的文件大小。
<field name="attachment" filename="attachment_fname" readonly="1"/>
<field name="attachment_fname" invisible="1"/>
二 多附件上传,图片点击放大
1 在model中增加下面的代码:
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', '=', 'hx.chp.changepoint'), ('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)
view_id = self.env.ref('hx_chp.view_document_file_kanban_hx').id,
domain = [('res_model', '=', self._name), ('res_id', '=', self.id)]
return {
'domain': domain,
'res_model': 'ir.attachment',
'name': u'附件管理',
'type': 'ir.actions.act_window',
'views': [(view_id, 'kanban'), (False, 'tree'), (False, 'form')],
'view_mode': 'kanban,tree,form',
'view_type': 'form',
'limit': 20,
'context': "{'default_res_model': '%s','default_res_id': %d}" % (self._name, self.id)
}
2 改写附件的kanban视图
在View中增加view_document_file_kanban_hx.xml 继承自mail.view_document_file_kanban
<odoo>
<record id="view_document_file_kanban_hx" model="ir.ui.view">
<field name="name">ir.attachment.kanban.inherit.hx</field>
<field name="model">ir.attachment</field>
<field name="inherit_id" ref="mail.view_document_file_kanban"/>
<field name="mode">primary</field>
<field name="arch" type="xml">
<xpath expr="//div[hasclass('o_kanban_image_wrapper')]" position="after">
<div class="imgfull">
<img t-attf-src="/web/image/#{record.id.raw_value}" alt="1111"/>
</div>
<script>
$(document).ready(function() {
$('.o_attachment_image').on('click',function(e){
let parent = $(this).parent();
let siblings = parent.siblings('.imgfull');
siblings.show();
});
$('.imgfull').on('click',function(e){
$(this).hide();
});
});
</script>
</xpath>
<xpath expr="//div[hasclass('oe_kanban_global_area')]" position="attributes">
<attribute name="class">oe_kanban_global_area o_kanban_attachment</attribute>
</xpath>
</field>
</record>
</odoo>
3 修改View文件
注意存放的位置,sheet里面第一个位置,不要放在group里面
<sheet>
<!-- 放在group外面-->
<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>
4 CSS
static/src/css/kanban.css
o_kanban_image{
position: relative;
}
.imgfull {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: auto;
display:none;
}
.imgfull img {
display: block;
width: 100%;
height: 100%;
object-fit: contain;
}
在清单文件中引入
'assets': {
'web.assets_backend': [
'hx_chp/static/src/**/*',
],
},