设为首页 加入收藏

TOP

odoo 给列表视图添加按钮实现数据文件导入(一)
2023-07-25 21:23:58 】 浏览:111
Tags:odoo 加按钮 文件导

实践环境

Odoo 14.0-20221212 (Community Edition)

代码实现

模块文件组织结构

说明:为了更好的表达本文主题,一些和主题无关的文件、代码已略去

odoo14\custom\estate
│  __init__.py
│  __manifest__.py
│
├─models
│  estate_customer.py
│  __init__.py
│
├─security
│      ir.model.access.csv
│
├─static
│  ├─img
│  │      icon.png
│  │
│  └─src
│      ├─js
│      │      estate_customer_tree_upload.js
│      │
│      └─xml
│              estate_customer_tree_view_buttons.xml
│
└─views
      estate_customer_views.xml
      estate_menus.xml
      webclient_templates.xml


测试模型定义

odoo14\custom\estate\models\estate_customer.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import base64
import openpyxl

from odoo.exceptions import UserError
from odoo import models, fields, _ # _ = GettextAlias()

from tempfile import TemporaryFile

class EstateCustomer(models.Model):
    _name = 'estate.customer'
    _description = 'estate customer'

    name = fields.Char(required=True)
    age = fields.Integer()
    description = fields.Text()

    def create_customer_from_attachment(self, attachment_ids=None):
        """
        :param attachment_ids: 上传的数据文件ID列表
        """

        attachments = self.env['ir.attachment'].browse(attachment_ids)
        if not attachments:
            raise UserError(_("未找到上传的文件"))

        for attachment in attachments:
            file_name_suffix = attachment.name.split('.')[-1]
            # 针对文本文件,暂时不实现数据存储,仅演示如何处理文本文件
            if file_name_suffix in ['txt', 'html']: # 文本文件
                lines = base64.decodebytes(attachment.datas).decode('utf-8').split('\n')
                for line in lines:
                    print(line)
            elif file_name_suffix in ['xlsx', 'xls']: # excel文件
                file_obj = TemporaryFile('w+b')
                file_obj.write(base64.decodebytes(attachment.datas))
                book = openpyxl.load_workbook(file_obj, read_only=False)
                sheets = book.worksheets
                for sheet in sheets:
                    rows = sheet.iter_rows(min_row=2, max_col=3) # 从第二行开始读取,每行读取3列
                    for row in rows:
                        name_cell, age_cell, description_cell = row
                        self.create({'name': name_cell.value, 'age': age_cell.value, 'description': description_cell.value})
            else:
                raise UserError(_("不支持的文件类型,暂时仅支持.txt,.html,.xlsx,.xls文件"))

            return {
                'action_type': 'reload', # 导入成功后,希望前端执行的动作类型, reload-刷新tree列表, do_action-执行action
            }

说明:

  • 函数返回值,具体需要返回啥,实际取决于下文js实现(上传成功后需要执行的操作),这里结合实际可能的需求,额外提供另外几种返回值供参考:

形式1:实现替换当前页面的效果

return {
    'action_type': 'do_action',
    'action': {
        'name': _('导入数据'),        
        'res_model': 'estate.customer',
        'views': [[False, "tree"]],
        'view_mode': 'tree',
        'type': 'ir.actions.act_window',
        'context': self._context,
        'target': 'main'
    }
}

形式2:弹出对话框效果

return {
    'action_type': 'do_action',
    'action': {
        'name': _('导入成功'),        
        'res_model': 'estate.customer.wizard',
        'views': [[False, "form"]],
        'view_mode': 'form',
        'type': 'ir.actions.act_window',
        'context': self._context,
        'target': 'new'
    }
}

说明:打开estate.customer.wizard默认form视图

形式3:实现类似浏览器刷新当前页面效果

return {
    'action_type': 'do_action',
    'action': {
        'type': 'ir.actions.client',
        'tag': 'reload' # 或者替换成 'tag': 'reload_context',
    }
}

odoo14\custom\estate\models\__init__.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from . import estate_customer

测试数据文件

mydata.xlsx

姓名 年龄 备注
张三 30 喜好运动
李四 28 喜欢美食
王五 23

测试模型视图定义

odoo14\custom\estate\views\estate_customer_views.xml

<?xml version="1.0"?>
<odoo>
    <record id="link_estate_
首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇【K哥爬虫普法】百度、360八年恩.. 下一篇加密,各种加密,耙梳加密算法(Encr..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目