模块名: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,
}