odoo启动-加载模块(load_modules)

这篇具有很好参考价值的文章主要介绍了odoo启动-加载模块(load_modules)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

odoo启动-加载模块(load_modules)

odoo每次启动的时候都会加载模块,加载模块的过程就是调用load_modules 函数

在函数位于 odoo\modules\loading.py

代码中注释也写的很清楚,共分了9个步骤,其实是8个步骤。

这个函数的作用是为一个新创建的注册表对象加载模块,这是Registry.new()的一部分,不应该用在其他地方。

def load_modules(registry, force_demo=False, status=None, update_module=False):
    """ Load the modules for a registry object that has just been created.  This
        function is part of Registry.new() and should not be used anywhere else.
    """
    initialize_sys_path()

    force = []
    if force_demo:
        force.append('demo')

    models_to_check = set()

    with registry.cursor() as cr:
        # prevent endless wait for locks on schema changes (during online
        # installs) if a concurrent transaction has accessed the table;
        # connection settings are automatically reset when the connection is
        # borrowed from the pool
        cr.execute("SET SESSION lock_timeout = '15s'")
        if not odoo.modules.db.is_initialized(cr):
            if not update_module:
                _logger.error("Database %s not initialized, you can force it with `-i base`", cr.dbname)
                return
            _logger.info("init db")
            odoo.modules.db.initialize(cr)
            update_module = True # process auto-installed modules
            tools.config["init"]["all"] = 1
            if not tools.config['without_demo']:
                tools.config["demo"]['all'] = 1

        if 'base' in tools.config['update'] or 'all' in tools.config['update']:
            cr.execute("update ir_module_module set state=%s where name=%s and state=%s", ('to upgrade', 'base', 'installed'))

        # STEP 1: LOAD BASE (must be done before module dependencies can be computed for later steps)
        graph = odoo.modules.graph.Graph()
        graph.add_module(cr, 'base', force)
        if not graph:
            _logger.critical('module base cannot be loaded! (hint: verify addons-path)')
            raise ImportError('Module `base` cannot be loaded! (hint: verify addons-path)')

        if update_module and odoo.tools.table_exists(cr, 'ir_model_fields'):
            # determine the fields which are currently translated in the database
            cr.execute("SELECT model || '.' || name FROM ir_model_fields WHERE translate IS TRUE")
            registry._database_translated_fields = {row[0] for row in cr.fetchall()}

        # processed_modules: for cleanup step after install
        # loaded_modules: to avoid double loading
        report = registry._assertion_report
        loaded_modules, processed_modules = load_module_graph(
            cr, graph, status, perform_checks=update_module,
            report=report, models_to_check=models_to_check)

        load_lang = tools.config.pop('load_language')
        if load_lang or update_module:
            # some base models are used below, so make sure they are set up
            registry.setup_models(cr)

        if load_lang:
            for lang in load_lang.split(','):
                tools.load_language(cr, lang)

        # STEP 2: Mark other modules to be loaded/updated
        if update_module:
            env = api.Environment(cr, SUPERUSER_ID, {})
            Module = env['ir.module.module']
            _logger.info('updating modules list')
            Module.update_list()

            _check_module_names(cr, itertools.chain(tools.config['init'], tools.config['update']))

            module_names = [k for k, v in tools.config['init'].items() if v]
            if module_names:
                modules = Module.search([('state', '=', 'uninstalled'), ('name', 'in', module_names)])
                if modules:
                    modules.button_install()

            module_names = [k for k, v in tools.config['update'].items() if v]
            if module_names:
                modules = Module.search([('state', 'in', ('installed', 'to upgrade')), ('name', 'in', module_names)])
                if modules:
                    modules.button_upgrade()

            env.flush_all()
            cr.execute("update ir_module_module set state=%s where name=%s", ('installed', 'base'))
            Module.invalidate_model(['state'])

        # STEP 3: Load marked modules (skipping base which was done in STEP 1)
        # IMPORTANT: this is done in two parts, first loading all installed or
        #            partially installed modules (i.e. installed/to upgrade), to
        #            offer a consistent system to the second part: installing
        #            newly selected modules.
        #            We include the modules 'to remove' in the first step, because
        #            they are part of the "currently installed" modules. They will
        #            be dropped in STEP 6 later, before restarting the loading
        #            process.
        # IMPORTANT 2: We have to loop here until all relevant modules have been
        #              processed, because in some rare cases the dependencies have
        #              changed, and modules that depend on an uninstalled module
        #              will not be processed on the first pass.
        #              It's especially useful for migrations.
        previously_processed = -1
        while previously_processed < len(processed_modules):
            previously_processed = len(processed_modules)
            processed_modules += load_marked_modules(cr, graph,
                ['installed', 'to upgrade', 'to remove'],
                force, status, report, loaded_modules, update_module, models_to_check)
            if update_module:
                processed_modules += load_marked_modules(cr, graph,
                    ['to install'], force, status, report,
                    loaded_modules, update_module, models_to_check)

        if update_module:
            # set up the registry without the patch for translated fields
            database_translated_fields = registry._database_translated_fields
            registry._database_translated_fields = ()
            registry.setup_models(cr)
            # determine which translated fields should no longer be translated,
            # and make their model fix the database schema
            models_to_untranslate = set()
            for full_name in database_translated_fields:
                model_name, field_name = full_name.rsplit('.', 1)
                if model_name in registry:
                    field = registry[model_name]._fields.get(field_name)
                    if field and not field.translate:
                        _logger.debug("Making field %s non-translated", field)
                        models_to_untranslate.add(model_name)
            registry.init_models(cr, list(models_to_untranslate), {'models_to_check': True})

        registry.loaded = True
        registry.setup_models(cr)

        # check that all installed modules have been loaded by the registry
        env = api.Environment(cr, SUPERUSER_ID, {})
        Module = env['ir.module.module']
        modules = Module.search(Module._get_modules_to_load_domain(), order='name')
        missing = [name for name in modules.mapped('name') if name not in graph]
        if missing:
            _logger.error("Some modules are not loaded, some dependencies or manifest may be missing: %s", missing)

        # STEP 3.5: execute migration end-scripts
        migrations = odoo.modules.migration.MigrationManager(cr, graph)
        for package in graph:
            migrations.migrate_module(package, 'end')

        # check that new module dependencies have been properly installed after a migration/upgrade
        cr.execute("SELECT name from ir_module_module WHERE state IN ('to install', 'to upgrade')")
        module_list = [name for (name,) in cr.fetchall()]
        if module_list:
            _logger.error("Some modules have inconsistent states, some dependencies may be missing: %s", sorted(module_list))

        # STEP 3.6: apply remaining constraints in case of an upgrade
        registry.finalize_constraints()

        # STEP 4: Finish and cleanup installations
        if processed_modules:
            env = api.Environment(cr, SUPERUSER_ID, {})

            cr.execute("SELECT model from ir_model")
            for (model,) in cr.fetchall():
                if model in registry:
                    env[model]._check_removed_columns(log=True)
                elif _logger.isEnabledFor(logging.INFO):    # more an info that a warning...
                    _logger.runbot("Model %s is declared but cannot be loaded! (Perhaps a module was partially removed or renamed)", model)

            # Cleanup orphan records
            env['ir.model.data']._process_end(processed_modules)
            env.flush_all()

        for kind in ('init', 'demo', 'update'):
            tools.config[kind] = {}

        # STEP 5: Uninstall modules to remove
        if update_module:
            # Remove records referenced from ir_model_data for modules to be
            # removed (and removed the references from ir_model_data).
            cr.execute("SELECT name, id FROM ir_module_module WHERE state=%s", ('to remove',))
            modules_to_remove = dict(cr.fetchall())
            if modules_to_remove:
                env = api.Environment(cr, SUPERUSER_ID, {})
                pkgs = reversed([p for p in graph if p.name in modules_to_remove])
                for pkg in pkgs:
                    uninstall_hook = pkg.info.get('uninstall_hook')
                    if uninstall_hook:
                        py_module = sys.modules['odoo.addons.%s' % (pkg.name,)]
                        getattr(py_module, uninstall_hook)(cr, registry)
                        env.flush_all()

                Module = env['ir.module.module']
                Module.browse(modules_to_remove.values()).module_uninstall()
                # Recursive reload, should only happen once, because there should be no
                # modules to remove next time
                cr.commit()
                _logger.info('Reloading registry once more after uninstalling modules')
                registry = odoo.modules.registry.Registry.new(
                    cr.dbname, force_demo, status, update_module
                )
                cr.reset()
                registry.check_tables_exist(cr)
                cr.commit()
                return registry

        # STEP 5.5: Verify extended fields on every model
        # This will fix the schema of all models in a situation such as:
        #   - module A is loaded and defines model M;
        #   - module B is installed/upgraded and extends model M;
        #   - module C is loaded and extends model M;
        #   - module B and C depend on A but not on each other;
        # The changes introduced by module C are not taken into account by the upgrade of B.
        if models_to_check:
            registry.init_models(cr, list(models_to_check), {'models_to_check': True})

        # STEP 6: verify custom views on every model
        if update_module:
            env = api.Environment(cr, SUPERUSER_ID, {})
            env['res.groups']._update_user_groups_view()
            View = env['ir.ui.view']
            for model in registry:
                try:
                    View._validate_custom_views(model)
                except Exception as e:
                    _logger.warning('invalid custom view(s) for model %s: %s', model, tools.ustr(e))

        if report.wasSuccessful():
            _logger.info('Modules loaded.')
        else:
            _logger.error('At least one test failed when loading the modules.')


        # STEP 8: save installed/updated modules for post-install tests and _register_hook
        registry.updated_modules += processed_modules

        # STEP 9: call _register_hook on every model
        # This is done *exactly once* when the registry is being loaded. See the
        # management of those hooks in `Registry.setup_models`: all the calls to
        # setup_models() done here do not mess up with hooks, as registry.ready
        # is False.
        env = api.Environment(cr, SUPERUSER_ID, {})
        for model in env.values():
            model._register_hook()
        env.flush_all()

0、初始化数据库

这里判断数据库有没有被初始化,如果没有,就安装base模块

    initialize_sys_path()

    force = []
    if force_demo:
        force.append('demo')

    models_to_check = set()

    with registry.cursor() as cr:
        # prevent endless wait for locks on schema changes (during online
        # installs) if a concurrent transaction has accessed the table;
        # connection settings are automatically reset when the connection is
        # borrowed from the pool
        cr.execute("SET SESSION lock_timeout = '15s'")
        if not odoo.modules.db.is_initialized(cr):
            if not update_module:
                _logger.error("Database %s not initialized, you can force it with `-i base`", cr.dbname)
                return
            _logger.info("init db")
            odoo.modules.db.initialize(cr)
            update_module = True # process auto-installed modules
            tools.config["init"]["all"] = 1
            if not tools.config['without_demo']:
                tools.config["demo"]['all'] = 1

        if 'base' in tools.config['update'] or 'all' in tools.config['update']:
            cr.execute("update ir_module_module set state=%s where name=%s and state=%s", ('to upgrade', 'base', 'installed'))

step 1、加载base模块

第一步就是加载base模块, 最后还加载了其他模块的语言包

SELECT model || '.' || name FROM ir_model_fields WHERE translate IS TRUE   #原来pg使用|| 来拼接字符串的。

registry._database_translated_fields = {row[0] for row in cr.fetchall()}    # 这个写法也很有意思,简洁
 # STEP 1: LOAD BASE (must be done before module dependencies can be computed for later steps)
        graph = odoo.modules.graph.Graph()
        graph.add_module(cr, 'base', force)
        if not graph:
            _logger.critical('module base cannot be loaded! (hint: verify addons-path)')
            raise ImportError('Module `base` cannot be loaded! (hint: verify addons-path)')

        if update_module and odoo.tools.table_exists(cr, 'ir_model_fields'):
            # determine the fields which are currently translated in the database
            cr.execute("SELECT model || '.' || name FROM ir_model_fields WHERE translate IS TRUE")
            registry._database_translated_fields = {row[0] for row in cr.fetchall()}   
  
        # processed_modules: for cleanup step after install
        # loaded_modules: to avoid double loading
        report = registry._assertion_report
        loaded_modules, processed_modules = load_module_graph(
            cr, graph, status, perform_checks=update_module,
            report=report, models_to_check=models_to_check)

        load_lang = tools.config.pop('load_language')
        if load_lang or update_module:
            # some base models are used below, so make sure they are set up
            registry.setup_models(cr)

        if load_lang:
            for lang in load_lang.split(','):
                tools.load_language(cr, lang)

控制台输出

2023-11-04 07:58:50,981 1340 INFO ? odoo.service.server: HTTP service (werkzeug) running on LAPTOP-AV3CF7SO:8069 
2023-11-04 07:58:50,987 1340 INFO odoo2 odoo.modules.loading: loading 1 modules...
2023-11-04 07:58:51,008 1340 INFO odoo2 odoo.modules.loading: 1 modules loaded in 0.02s, 0 queries (+0 extra) 
2023-11-04 07:58:51,154 1340 INFO odoo2 odoo.addons.base.models.ir_module: module base: loading translation file zh_CN for language zh_CN 
2023-11-04 07:58:52,077 1340 INFO odoo2 odoo.addons.base.models.ir_module: module web: loading translation file zh_CN for language zh_CN 
2023-11-04 07:58:52,256 1340 INFO odoo2 odoo.addons.base.models.ir_module: module base_setup: loading translation file zh_CN for language zh_CN 
2023-11-04 07:58:52,282 1340 INFO odoo2 odoo.addons.base.models.ir_module: module bus: loading translation file zh_CN for language zh_CN 
2023-11-04 07:58:52,295 1340 INFO odoo2 odoo.addons.base.models.ir_module: module web_tour: loading translation file zh_CN for language zh_CN 
2023-11-04 07:58:52,304 1340 INFO odoo2 odoo.addons.base.models.ir_module: module mail: loading translation file zh_CN for language zh_CN 
中间省略N行....
sql_constraint:cf.report.define.field 
2023-11-04 07:58:54,087 1340 INFO odoo2 odoo.tools.translate: Skipped deprecated occurrence sql_constraint:cf.report.define
2023-11-04 07:58:54,087 1340 INFO odoo2 odoo.tools.translate: Skipped deprecated occurrence selection:cf.report.define,state
2023-11-04 07:58:54,094 1340 INFO odoo2 odoo.addons.base.models.ir_module: module estate: no translation for language zh_CN
2023-11-04 07:58:54,102 1340 INFO odoo2 odoo.addons.base.models.ir_module: module hx_base: no translation for language zh_CN 
2023-11-04 07:58:54,115 1340 INFO odoo2 odoo.addons.base.models.ir_module: module hx_chp: no translation for language zh_CN 
2023-11-04 07:58:54,122 1340 INFO odoo2 odoo.addons.base.models.ir_module: module hx_gift: no translation for language zh_CN
2023-11-04 07:58:54,129 1340 INFO odoo2 odoo.addons.base.models.ir_module: module hx_jixiao: no translation for language zh_CN 
2023-11-04 07:58:54,136 1340 INFO odoo2 odoo.addons.base.models.ir_module: module hx_tsl: no translation for language zh_CN
2023-11-04 07:58:54,143 1340 INFO odoo2 odoo.addons.base.models.ir_module: module auth_totp: loading translation file zh_CN for 

step 2、加载或者升级其他模块

        # STEP 2: Mark other modules to be loaded/updated
        if update_module:
            env = api.Environment(cr, SUPERUSER_ID, {})
            Module = env['ir.module.module']
            _logger.info('updating modules list')
            Module.update_list()

            _check_module_names(cr, itertools.chain(tools.config['init'], tools.config['update']))

            module_names = [k for k, v in tools.config['init'].items() if v]
            if module_names:
                modules = Module.search([('state', '=', 'uninstalled'), ('name', 'in', module_names)])
                if modules:
                    modules.button_install()

            module_names = [k for k, v in tools.config['update'].items() if v]
            if module_names:
                modules = Module.search([('state', 'in', ('installed', 'to upgrade')), ('name', 'in', module_names)])
                if modules:
                    modules.button_upgrade()

            env.flush_all()
            cr.execute("update ir_module_module set state=%s where name=%s", ('installed', 'base'))
            Module.invalidate_model(['state'])

如果没有,这一步就跳过了

step 3、加载除了base之外的其他模块

1、分两个步骤完成,第一步加载所有已经安装的或者部分安装(需要升级),为第二步提供一个一致性的系统。第二步是安装新的模块。

我们在第一步中考虑了to_remove 的模块,因为他们是“已安装”模块的一部分, 他们将在step 6 去处理。

2、这里不得不循环处理,因为要处理模块之间的依赖关系

# STEP 3: Load marked modules (skipping base which was done in STEP 1)
        # IMPORTANT: this is done in two parts, first loading all installed or
        #            partially installed modules (i.e. installed/to upgrade), to
        #            offer a consistent system to the second part: installing
        #            newly selected modules.
        #            We include the modules 'to remove' in the first step, because
        #            they are part of the "currently installed" modules. They will
        #            be dropped in STEP 6 later, before restarting the loading
        #            process.
        # IMPORTANT 2: We have to loop here until all relevant modules have been
        #              processed, because in some rare cases the dependencies have
        #              changed, and modules that depend on an uninstalled module
        #              will not be processed on the first pass.
        #              It's especially useful for migrations.
        previously_processed = -1
        #  循环加载处理相关模块
        while previously_processed < len(processed_modules):
            previously_processed = len(processed_modules)
            processed_modules += load_marked_modules(cr, graph,
                ['installed', 'to upgrade', 'to remove'],
                force, status, report, loaded_modules, update_module, models_to_check)
            if update_module:
                processed_modules += load_marked_modules(cr, graph,
                    ['to install'], force, status, report,
                    loaded_modules, update_module, models_to_check)
		
        # 处理需要升级的模块
        if update_module:
            # set up the registry without the patch for translated fields
            database_translated_fields = registry._database_translated_fields
            registry._database_translated_fields = ()
            registry.setup_models(cr)
            # determine which translated fields should no longer be translated,
            # and make their model fix the database schema
            models_to_untranslate = set()
            for full_name in database_translated_fields:
                model_name, field_name = full_name.rsplit('.', 1)
                if model_name in registry:
                    field = registry[model_name]._fields.get(field_name)
                    if field and not field.translate:
                        _logger.debug("Making field %s non-translated", field)
                        models_to_untranslate.add(model_name)
            registry.init_models(cr, list(models_to_untranslate), {'models_to_check': True})

        registry.loaded = True
        registry.setup_models(cr)

        # check that all installed modules have been loaded by the registry
        env = api.Environment(cr, SUPERUSER_ID, {})
        Module = env['ir.module.module']
        modules = Module.search(Module._get_modules_to_load_domain(), order='name')
        missing = [name for name in modules.mapped('name') if name not in graph]
        if missing:
            _logger.error("Some modules are not loaded, some dependencies or manifest may be missing: %s", missing)

        # STEP 3.5: execute migration end-scripts
        migrations = odoo.modules.migration.MigrationManager(cr, graph)
        for package in graph:
            migrations.migrate_module(package, 'end')

        # check that new module dependencies have been properly installed after a migration/upgrade
        cr.execute("SELECT name from ir_module_module WHERE state IN ('to install', 'to upgrade')")
        module_list = [name for (name,) in cr.fetchall()]
        if module_list:
            _logger.error("Some modules have inconsistent states, some dependencies may be missing: %s", sorted(module_list))

        # STEP 3.6: apply remaining constraints in case of an upgrade
        registry.finalize_constraints()

控制台输出:

2023-11-04 08:16:23,488 11076 INFO odoo2 odoo.modules.loading: loading 54 modules... 
2023-11-04 08:16:23,882 11076 WARNING odoo2 odoo.api.create: The model odoo.addons.hx_chp.models.change_point is not overriding the create method 

2023-11-04 08:16:23,944 11076 WARNING odoo2 odoo.api.create: The model odoo.addons.hx_tsl.models.hx_tsl_info is not overriding the create method in batch
2023-11-04 08:16:24,292 11076 WARNING odoo2 odoo.api.create: The model odoo.addons.cfprint.models.cfprint_server_user_map is not overriding the create method in batch
2023-11-04 08:16:25,047 11076 WARNING odoo2 odoo.api.create: The model odoo.addons.cf_report_designer.models.data_model_3 is not overriding the create method in batch
2023-11-04 08:16:25,069 11076 WARNING odoo2 odoo.api.create: The model odoo.addons.cf_report_designer.models.data_model_4 is not overriding the create method in batch
2023-11-04 08:16:25,071 11076 WARNING odoo2 odoo.api.create: The model odoo.addons.cf_report_designer.models.data_model_4 is not overriding the create method in batch
2023-11-04 08:16:25,416 11076 INFO odoo2 odoo.modules.loading: 54 modules loaded in 1.93s, 0 queries (+0 extra) 

step 4、完成并且清理安装过程

基本就是一些善后过程,正常情况下不会执行

# STEP 4: Finish and cleanup installations
        if processed_modules:
            env = api.Environment(cr, SUPERUSER_ID, {})

            cr.execute("SELECT model from ir_model")
            for (model,) in cr.fetchall():
                if model in registry:
                    env[model]._check_removed_columns(log=True)
                elif _logger.isEnabledFor(logging.INFO):    # more an info that a warning...
                    _logger.runbot("Model %s is declared but cannot be loaded! (Perhaps a module was partially removed or renamed)", model)

            # Cleanup orphan records
            env['ir.model.data']._process_end(processed_modules)
            env.flush_all()

        for kind in ('init', 'demo', 'update'):
            tools.config[kind] = {}

step 5、卸载相关模块

SELECT name, id FROM ir_module_module WHERE state=%s", ('to remove',)

如果配置了uninstall_hook,要在这里执行。 然后调用module_uninstall()方法来卸载

Module.browse(modules_to_remove.values()).module_uninstall()

卸载完成之后,刷新注册表。

5.5 是要处理一些模型之间的依赖关系。

# STEP 5: Uninstall modules to remove
        if update_module:
            # Remove records referenced from ir_model_data for modules to be
            # removed (and removed the references from ir_model_data).
            cr.execute("SELECT name, id FROM ir_module_module WHERE state=%s", ('to remove',))
            modules_to_remove = dict(cr.fetchall())
            if modules_to_remove:
                env = api.Environment(cr, SUPERUSER_ID, {})
                pkgs = reversed([p for p in graph if p.name in modules_to_remove])
                for pkg in pkgs:
                    uninstall_hook = pkg.info.get('uninstall_hook')
                    if uninstall_hook:
                        py_module = sys.modules['odoo.addons.%s' % (pkg.name,)]
                        getattr(py_module, uninstall_hook)(cr, registry)
                        env.flush_all()

                Module = env['ir.module.module']
                Module.browse(modules_to_remove.values()).module_uninstall()
                # Recursive reload, should only happen once, because there should be no
                # modules to remove next time
                cr.commit()
                _logger.info('Reloading registry once more after uninstalling modules')
                registry = odoo.modules.registry.Registry.new(
                    cr.dbname, force_demo, status, update_module
                )
                cr.reset()
                registry.check_tables_exist(cr)
                cr.commit()
                return registry

        # STEP 5.5: Verify extended fields on every model
        # This will fix the schema of all models in a situation such as:
        #   - module A is loaded and defines model M;
        #   - module B is installed/upgraded and extends model M;
        #   - module C is loaded and extends model M;
        #   - module B and C depend on A but not on each other;
        # The changes introduced by module C are not taken into account by the upgrade of B.
        if models_to_check:
            registry.init_models(cr, list(models_to_check), {'models_to_check': True})

step 6、确认每个模型相关的视图

        # STEP 6: verify custom views on every model
        if update_module:
            env = api.Environment(cr, SUPERUSER_ID, {})
            env['res.groups']._update_user_groups_view()
            View = env['ir.ui.view']
            for model in registry:
                try:
                    View._validate_custom_views(model)
                except Exception as e:
                    _logger.warning('invalid custom view(s) for model %s: %s', model, tools.ustr(e))

        if report.wasSuccessful():
            _logger.info('Modules loaded.')
        else:
            _logger.error('At least one test failed when loading the modules.')

控制台输出

2023-11-04 08:35:43,841 11076 INFO odoo2 odoo.modules.loading: Modules loaded. 

step 8、保存安装或者升级的视图

为了post-install测试 和调用_register_hook, step7 哪去了????

        # STEP 8: save installed/updated modules for post-install tests and _register_hook
        registry.updated_modules += processed_modules

step 9、调用_register_hook

对每个model模型调用_register_hook,每次启动的时候都会调用,能干什么呢?

        # STEP 9: call _register_hook on every model
        # This is done *exactly once* when the registry is being loaded. See the
        # management of those hooks in `Registry.setup_models`: all the calls to
        # setup_models() done here do not mess up with hooks, as registry.ready
        # is False.
        env = api.Environment(cr, SUPERUSER_ID, {})
        for model in env.values():
            model._register_hook()
        env.flush_all()

models.py

    def _register_hook(self):
        """ stuff to do right after the registry is built """

    def _unregister_hook(self):
        """ Clean up what `~._register_hook` has done. """

_register_hook 有什么用?

可以在模块加载完之后动态修改模型的一些属性值。

比如修改_rec_name

def  _register_hook(self):
	setattr(type(self),'_rec_name', 'myname')

安装模块的时候也会执行load_modules函数重新加载所有的模块,如果你希望你的逻辑只有在启动的时候执行而不是安装模块的时候执行,在context中有个变量可以区分。

哪个变量?文章来源地址https://www.toymoban.com/news/detail-742445.html

到了这里,关于odoo启动-加载模块(load_modules)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • React16源码: React中的异步调度scheduler模块的源码实现

    React Scheduler 1 ) 概述 react当中的异步调度,称为 React Scheduler 发布成单独的一个 npm 包就叫做 scheduler 这个包它做了什么? A. 首先它维护时间片 B. 然后模拟 requestIdleCallback 这个API 因为现在浏览器的支持不是特别的多 所以在浏览当中只是去模拟了一个这个API,而不是直接使用这

    2024年01月18日
    浏览(44)
  • win10 搭建odoo16环境(docker或本地)

    一、 1.安装docker,下载docker工具 本人使用docker_toolbox进行安装,此处需注意git的path 创建default虚拟机,国内下载iso文件可能存在问题, 使用已下载好的iso文件 地址:https://github.com/boot2docker/boot2docker/releases 也可联系博主咨询 a.将文件放在 C:UsersAdministrator.dockermachinecache目录

    2024年02月08日
    浏览(48)
  • odoo16 销售订单中数量与单价,手机录入不方便

    odoo16 销售订单中数量与单价,手机录入不方便 在销售订单中,服装批发,数量与单价均是整数,系统默认的为保留两位小数的float类型,输入起来很不方便,如何修改 电脑版,输入时,自动选取,点取数字后直接录入,很方便,但手机界面不行,1.00还需从后面删除,直接录

    2024年02月01日
    浏览(37)
  • odoo16实用功能之创建/自定义服务器动作

    目录 1、什么是服务器动作(ir.actions.server) 2、编写需要执行的python函数 3、编写动作 效果图: 参数说明: 在Odoo中,服务器动作(Server Action)是一种执行预定义操作的机制,通常在后端执行。它们可以在各种场景下用于自动化和扩展功能。以下是一些服务器动作的应用场景

    2024年01月19日
    浏览(42)
  • 如何利用产品状态维度优化库存管理和采购策略?【ODOO15/16】

           ODOO产品属性有个分类维度值,很多人不明白具体该怎么用?其实用处很大,我们首先要确立一个观点:没有分类就没有管理!公司里那么多产品,都有不同的特性、用途、价值,我们只有进行准确分类,才能针对性的管理。       ODOO的分类设置界面:      以下我

    2024年02月07日
    浏览(34)
  • Nginx + Docker 极简部署 Odoo16 支持 HTTPS 避坑指南

    在生产环境使用 Odoo 官方 Docker 镜像部署 odoo16,使用 Nginx 作为反向代理,并支持 Https协议,记录遇到的问题,作为避坑指南,最后推荐一个免费的符合OpenAPI规范的接口模块。 centos7 docker V23 nginx https 证书 Odoo 模块 安装 docker 及 docker compose (非 docker-compose 无下划线) 启动 docke

    2024年02月06日
    浏览(35)
  • 【企业信息化】第2集 免费开源ERP: Odoo 16 销售管理系统

    世界排名第一的免费开源ERP: Odoo 16 销售管理系统。通过Odoo Sign应用程序和在线支付,发送报价。 通过清晰报价提高销售量 以专业方式展示产品和服务。 向潜在客户发送清晰且完整的报价单。只需简单拖放构建模块,即可轻松添加产品说明、漂亮的图像以及其他信息。 设计

    2024年02月06日
    浏览(57)
  • odoo安装启动遇到的问题

    问题:在第一次加载odoo配置文件的时候,启动失败 方法: 1、先检查odoo.conf的内容,尤其是路径 2、然后在Run /Debug Configurations 里输入 -i base -d 新数据库名 3、 重启服务器看可不可以,如果还不行就重装下把数据库删除新建一个或者需要重装数据库,更改一下数据库的版本,

    2024年02月11日
    浏览(35)
  • odoo 开发入门教程系列-模块交互

    在上一章中,我们使用继承来修改模块的行为。在我们的房地产场景中,我们希望更进一步,能够为客户生成发票。Odoo提供了一个开发票模块,因此直接从我们的房地产模块创建发票是很简单的,也就是说,一旦某个房产设置为“已售出”,就会在 Invoicing 应用程序中创建发

    2023年04月16日
    浏览(39)
  • Docker打包容器并跨服务器传输重建加载load镜像Unable to find image :latest问题解决 及 Docker在容器未启动的情况下如何修改容器中文件

        使用docker就是因为docker可以快速进行多服务器部署,所以需要对部署好的环境进行打包复制并快速在其它的服务器上进行重建。     其实使用起来非常简单,使用docker export从运行的容器中导出文件,,使用import命令生成镜像批量传至目标服务器然后在目标服务器上进行

    2024年04月17日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包