odoo10 附件模块的两个实际应用

---
title: 2018-7-24 附件模块学习 
tags: attachment
grammar_cjkRuby: true
---


1.安装附件模块(document,安装后会在form表单上方增加"attachment(s)"下拉选项)
主要是打开附件功能的界面以及上传文件的功能(该模块的model/ir_attachment.py)
实际附件核心在 odoo/addons/base/ir/ir_attachment.py

2.附件与模块无具体对应的关联表,附件统一保存在ir_attachment数据表里

3.附件的**定位方式**大概是 通过 res_model和res_id两个字段,定位到具体某模块的某条记录

4.如果字段加了attachment=True属性 那么该字段保存的文件(图片)也将当作 附件存储  ,我称为该附件为*字段附件*,通过点击attachment的add直接添加的附件为 *标准附件*。这两种附件的字段区分以 **res_field字段**是否为空为准,有field依赖则为字段附件(res_field在需要获取所有附件的情景有用处)

5.附件的**存储方式**是通过对附件数据生成一串唯一的hash值,然后用**store_fname字段**存储软地址的形式,告知odoo附件的存储位置,这样重复上传相同文件,此时系统不会再次重复上传,避免了不必要的开销,并增加一条对该附件的引用记录,删除操作则相反,当对该附件的引用记录为0时,系统将会删除该附件。

PS:在odoo的conf配置中,data_dir可以自定义数据存储路径(我在中途增加过该配置,但是重启后odoo的页面找不到css等路径,页面布局全乱了,目前未找到解决方案)


实例1:
1.说明:目前公司业务需要将前面的贷款业务(4个模型)中的所有附件保存到新模块(loan.record)中
2.达到的效果:降低前后模块的耦合,保证之前(4个模型)的记录删除后,新模块的附件不受影响

思路:(例子详情请见post_loan模块的inherit_apply.py)

1.生成一条(record模块)新记录

``` python
res = self.env['loan.record'].sudo().create(val)
if res:
    self.get_relation_attachment_ids(res)
```


2.查询并获取所有模块中的所有附件(标准附件和字段附件)

``` python
def get_relation_attachment_ids(self,res):
    ...
    # 根据res_model和res_id查询客户录入单附件
    borrower_attachment = attachment_model.sudo().search([
                ('res_model', '=', self.borrower_id._name), ('res_id', '=', self.borrower_id.id),
                '|', '|', ('res_field', '=', None), ('res_field', '=', 'frontimage'),
                ('res_field', '=', 'backimage')])
    ...
    self.copy_attachment_data(res,borrower_attachment)
```


3.使用该新记录集的id(步骤1时生成的) 和模型名 生成一条 该记录 对 附件的引用(也就是增加一条附件引用记录,达到实例1的效果)  

``` python
def copy_attachment_data(self,record,attachments):
    # 循环附件的记录集(通常不止一个附件记录)
    for attachment in attachments:
        # 复制一份附件数据(返回list包dict的数据类型)
        data = attachment.copy_data()[0]
        # 根据模型名来给对应的附件改名
        if data['res_model']=='loan.borrower':
            if data['res_field']=='frontimage':
                data['name'] =u'身份证正面(%s)' % attachment.res_name
        ...
        
        # 最重要的是以下步骤
        data['res_model'] = record._name
        data['res_id'] = record.id
        # 增加附件引用记录
        self.env['ir.attachment'].sudo().create(data)
```


实例2:(附件预览)
直接点击

标题


弹出新窗口查看该记录引用的附件

直接上代码:
函数

    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)
        }


页面按钮
xml

            <sheet>
                    <div class="oe_button_box" name="button_box">
                        <button name="attachment_image_preview"
                                type="object" class="oe_stat_button" icon="fa-image">
                            <!--<field name="img_count" widget="statinfo"/>-->
                            <div class="o_stat_info">
                                <span class="o_stat_text">附件管理</span>
                            </div>
                        </button>
                    </div>


 

猜你喜欢

转载自blog.csdn.net/qq_19343775/article/details/81186898