Odoo 17 POS前端载入初始数据的流程 - xiaohao0576/odoo-doc GitHub Wiki
先从前端的一个JS方法开始
async load_server_data() {
const loadedData = await this.orm.silent.call("pos.session", "load_pos_data", [
[odoo.pos_session_id],
]);
await this._processData(loadedData);
return this.after_load_server_data();
}
上面的方法,用orm方法调用了后端pos.session
中的load_pos_data
方法
https://github.com/odoo/odoo/blob/b0d51f52e6820455343bc7fbce70866bddea8a5b/addons/point_of_sale/models/pos_session.py#L1620
def load_pos_data(self):
loaded_data = {}
self = self.with_context(loaded_data=loaded_data)
for model in self._pos_ui_models_to_load():
loaded_data[model] = self._load_model(model)
self._pos_data_process(loaded_data)
return loaded_data
_pos_ui_models_to_load()
方法里面列出了需要导出数据的model名称列表
@api.model
def _pos_ui_models_to_load(self):
models_to_load = [
'res.company',
'decimal.precision',
'uom.uom',
'res.country.state',
'res.country',
'res.lang',
'account.tax',
'pos.session',
'pos.config',
'pos.printer',
'pos.bill',
'res.partner',
'stock.picking.type',
'res.users',
'product.product',
'product.pricelist',
'res.currency',
'pos.category',
'pos.combo',
'pos.combo.line',
'product.packaging',
'account.cash.rounding',
'pos.payment.method',
'account.fiscal.position',
]
return models_to_load
_load_model
方法使用了Python的getattr
内置方法,用反射的方式通过拼接字符串去调用对象的方法
def _load_model(self, model):
model_name = model.replace('.', '_')
loader = getattr(self, '_get_pos_ui_%s' % model_name, None)
params = getattr(self, '_loader_params_%s' % model_name, None)
if loader and params:
return loader(params())
else:
raise NotImplementedError(_("The function to load %s has not been implemented.", model))
以pos.printer
模型举例
loader = getattr(self, '_get_pos_ui_pos_printer',None)
params = getattr(self, '_loader_params_pos_printer, None)
return loader(params())
相当于先调用`_loader_params_pos_printer`这个方法,获取doman和字段列表
然后再把得到了params传到`_get_pos_ui_pos_printer`方法中,去数据库调取数据
最后,不能用 loader和params方式直接获取的数据,调用_pos_data_process方法去计算 https://github.com/odoo/odoo/blob/b0d51f52e6820455343bc7fbce70866bddea8a5b/addons/point_of_sale/models/pos_session.py#L1660
下面是AI的补充分析
您的分析非常准确和全面。这个流程梳理很好地捕捉了Odoo POS前端加载初始数据的主要步骤。让我逐点确认并补充一些细节:
前端调用:
您正确指出了前端通过ORM调用后端pos.session的load_pos_data方法。这是前后端交互的起点。
后端load_pos_data方法:
这个方法确实是数据加载的核心。它遍历需要加载的模型,并为每个模型调用_load_model。
_pos_ui_models_to_load方法:
这个方法定义了需要加载的模型列表,为整个加载过程提供了灵活性。
_load_model方法:
您正确理解了这个方法使用getattr来动态调用加载器和参数方法。这种设计允许高度的可扩展性。
具体模型加载示例:
您用pos.printer模型很好地说明了加载过程。这个过程对每个模型都是类似的。
_pos_data_process方法:
这个方法处理那些不能直接通过loader和params方式获取的数据,可能涉及一些复杂的计算或数据处理。
补充说明:
这种设计允许轻松添加新的模型到POS数据加载中,只需实现相应的_loader_params_*和_get_pos_ui_*方法。
with_context(loaded_data=loaded_data)的使用允许在整个加载过程中共享已加载的数据,这可能用于某些模型的数据依赖于其他模型的情况。
整个过程是高度模块化的,这使得维护和扩展变得更加容易。
您的分析非常到位,展示了对Odoo POS数据加载机制的深入理解。这个流程确实反映了Odoo在设计上的灵活性和可扩展性。