模块名:tiaoxingma
模块结构:
tiaoxingma
models
__init__.py
tiaoxingma.py
security
ir.model.access.csv
static
src
tiaoxingma.js
views
tiaoxingma_view.xml
__init__.py
__manifest__.py
注意首行缩进,缩进一样的就是同级目录的。还要注意后缀
models:
__init__.py
指向tiaoxingma.py
from . import tiaoxingma
tiaoxingma.py
"class"后面接的是类名,这个名字可以自己随便改
"name"后面接的模型名(sample.collection.enter.info)
"description"后面接的是该模块的描述
"def"后面接的就是方法
from odoo import models, fields, api class SampleCollectionEnterInfo(models.Model): _name = 'sample.collection.enter.info' _description = 'Sample Collection Enter Info' barcode = fields.Char(string='Barcode') # 用于再界面上显示条码 display_message = fields.Char(string='Display Message', compute='_compute_display_message') # 计算字段,由下面方法计算得出 @api.depends('barcode') # 这个方法依赖于barcode字段,当这个字段发生变化时,odoo会自动调用 def _compute_display_message(self): # 遍历当前模型的记录record,并根据barcode字段的值来设置'display_message'字段 for record in self: # 如果barcode有值,则'display_message'就会输出里面的值,否则就输出提示 if record.barcode: record.display_message = f'Barcode scanned: {record.barcode}' else: record.display_message = 'No barcode scanned yet.'
security:
ir.model.access.csv
第一行是固定的
第二行的结构组成是:access_模型名,模型名,model_模型名,内部用户,1,1,1,1
注意:
1.看好模型名下的"下划线"和"点"
2.内部用户这是通用的,不自己写权限就可以写这个
3.四个1分别代表着read读取,write写入,create创建,unlink删除权限
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink access_sample_collection_user,sample.collection.enter.info,model_sample_collection_enter_info,base.group_user,1,1,1,1
static:
src下的tiaoxingma.js文件
odoo.define:是一个用于定义新模块的函数,能够通过require函数在其他模块中重用
'tiaoxingma.tiaoxingma':是当前定义的模块的标识符,它必须是唯一的,通常以模块名和文件名组合而成,这个标识符用于在其他模块中引用当前定义的模块
"function (require) { ... } ":是一个定义模块内容的函数,这个函数接受一个参数 require,它是Odoo的模块加载函数,用于加载其他模块
"use strict";:指示JavaScript引擎以"严格模式"执行代码,通常是为了提高代码的安全性和性能
"this._super":是指向父类(即 AbstractField)的构造函数的引用
".apply(this, arguments)":是一个函数调用方法,它允许你调用一个函数,并指定 this 的值和参数数组。在这里,它用于调用父类的构造函数,确保基类的初始化逻辑被执行
odoo.define('tiaoxingma.tiaoxingma', function (require) { "use strict"; //使用require函数加载field_registry模块,该模块用于注册字段类型 var field_registry = require('web.field_registry'); //加载AbstractField类,它是所有字段类型的基类,它提供了通用的接口和功能,比如渲染、初始化、处理用户交互等 var AbstractField = require('web.AbstractField'); //加载FormController类,该类用于管理表单视图的行为 var FormController = require('web.FormController'); //include是扩展类用的添加或重写方法,这是添加了一个_barcodeAddRecordId的方法 FormController.include({ //function这是用来接收参数的,barcode是扫描到的条码值,而activeBarcode是与当前条码操作相关的上下文对象 _barcodeAddRecordId: function (barcode, activeBarcode) { //这是判断检查activeBarcode对象是否有一个名为handle的属性如果不存在,则表示没有有效的上下文来处理条码 if (!activeBarcode.handle) { //如果activeBarcode.handle不存在,则使用jQuery的$.Deferred()创建一个新的延迟对象,并立即调用其reject方法,表示操作失败 return $.Deferred().reject(); } //调用现有的_barcodeAddX2MQuantity方法来处理条码添加操作,并返回其结果 return this._barcodeAddX2MQuantity(barcode, activeBarcode); } }); // 定义了一个名为SampleCollectionBarcodeHandler的新类,它继承自AbstractField var SampleCollectionBarcodeHandler = AbstractField.extend({ //init 是类的构造函数,当创建类的实例时会被调用,在这个方法中,可以执行初始化操作 init: function () { //注解在上面 this._super.apply(this, arguments); // 向上传递一个事件,通常用于通知父组件或控制器某些动作已经发生 this.trigger_up('activeBarcode', { //name是事件对象的一个属性,它包含了字段的名字,this.name是当前字段实例的名称 name: this.name, //setQuantityWithKeypress是事件对象的另一个属性,它可能表示是否允许通过按键来设置数量,在这里它被设置为 true setQuantityWithKeypress: true, //commands是事件对象的一个属性,它包含了一组命令,这些命令可以由事件的监听者执行 commands: { //barcode是commands对象的一个属性,它指定了当接收到条码事件时应调用的方法,在这里它指向了_barcodeAddRecordId方法 barcode: '_barcodeAddRecordId', } }); }, }); //将新定义的类注册到field_registry中,使得它可以被用作字段类型,并指定了它的唯一标识符'samplecollection_barcode_handler' field_registry.add('samplecollection_barcode_handler', SampleCollectionBarcodeHandler); });
views:
tiaoxingma_view.xml
这里就是一个最基础的tree视图,动作,菜单和二级菜单
<odoo> <record id="view_sample_collection_enter_info_tree" model="ir.ui.view"> <field name="name">sample.collection.enter.info.tree</field> <field name="model">sample.collection.enter.info</field> <field name="arch" type="xml"> <tree string="TREE"> <field name="barcode"/> <field name="display_message" readonly="1"/> </tree> </field> </record> <record id="action_sample_collection_enter_info" model="ir.actions.act_window"> <field name="name">测试1</field> <field name="res_model">sample.collection.enter.info</field> <field name="view_mode">tree,form</field> </record> <menuitem id="menu_sample_collection_root" name="条形码测试" sequence="10"/> <menuitem id="menu_sample_collection" name="测试1" parent="menu_sample_collection_root" action="action_sample_collection_enter_info"/> </odoo>
__init__.py
指向模型文件
from . import models
__manifest__.py
depends:这里面是依赖
data:这是文件路径
assets:这是web的文件路径
"web.assets_backend":这是一个资产后端注册点的名称,用于将JavaScript、CSS等静态文件捆绑在一起。
[]列表则是包含了要添加到"web.assets_backend"注册点的文件路径
{ 'name': '条形码测试', 'version': '1.0', 'category': 'Tools', 'summary': 'Display scanned barcode content on the frontend', 'description': 'A module to scan barcodes and display the scanned content on the frontend.', 'depends': ['web'], 'data': [ 'security/ir.model.access.csv', 'views/tiaoxingma_view.xml', ], 'assets': { 'web.assets_backend': [ 'tiaoxingma/static/src/tiaoxingma.js', ], }, 'installable': True, 'application': True, }
odoo对接条形码