背景:同一个模块,两组开发人员对同一个模型的form视图进行了二开。在没有指定外部ID的情况下,odoo是如何选择展示展示哪个视图呢?
上干货
load_views函数; @api.model
def load_views(self, views, options=None):
""" Returns the fields_views of given views, along with the fields of
the current model, and optionally its filters for the given action.
:param views: list of [view_id, view_type]
:param options['toolbar']: True to include contextual actions when loading fields_views
:param options['load_filters']: True to return the model's filters
:param options['action_id']: id of the action to get the filters
:return: dictionary with fields_views, fields and optionally filters
"""
options = options or {}
result = {}
toolbar = options.get('toolbar')
result['fields_views'] = {
v_type: self.fields_view_get(v_id, v_type if v_type != 'list' else 'tree',
toolbar=toolbar if v_type != 'search' else False)
for [v_id, v_type] in views
}
result['fields'] = self.fields_get()
if options.get('load_filters'):
result['filters'] = self.env['ir.filters'].get_filters(self._name, options.get('action_id'))
return result
fields_view_get函数,如下,截取重要的内容 @api.model
def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
self.check_access_rights('read')
view = self.env['ir.ui.view'].sudo().browse(view_id)
# Get the view arch and all other attributes describing the composition of the view
result = self._fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu)
···
_fields_view_get函数,若用户调用的视图没有指定视图ID,那么将调用默认的视图 @api.model
def _fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
View = self.env['ir.ui.view'].sudo()
result = {
'model': self._name,
'field_parent': False,
}
# try to find a view_id if none provided
if not view_id:
# <view_type>_view_ref in context can be used to overrride the default view
view_ref_key = view_type + '_view_ref'
view_ref = self._context.get(view_ref_key)
if view_ref:
if '.' in view_ref:
module, view_ref = view_ref.split('.', 1)
query = "SELECT res_id FROM ir_model_data WHERE model='ir.ui.view' AND module=%s AND name=%s"
self._cr.execute(query, (module, view_ref))
view_ref_res = self._cr.fetchone()
if view_ref_res:
view_id = view_ref_res[0]
else:
_logger.warning('%r requires a fully-qualified external id (got: %r for model %s). '
'Please use the complete `module.view_id` form instead.', view_ref_key, view_ref,
self._name)
if not view_id:
# otherwise try to find the lowest priority matching ir.ui.view
view_id = View.default_view(self._name, view_type)
if view_id:
# read the view with inherited views applied
root_view = View.browse(view_id).read_combined(['id', 'name', 'field_parent', 'type', 'model', 'arch'])
result['arch'] = root_view['arch']
result['name'] = root_view['name']
result['type'] = root_view['type']
result['view_id'] = root_view['id']
result['field_parent'] = root_view['field_parent']
result['base_model'] = root_view['model']
else:
# fallback on default views methods if no ir.ui.view could be found
try:
arch_etree = getattr(self, '_get_default_%s_view' % view_type)()
result['arch'] = etree.tostring(arch_etree, encoding='unicode')
result['type'] = view_type
result['name'] = 'default'
except AttributeError:
raise UserError(_("No default view of type '%s' could be found !", view_type))
return result
default_view函数查看 @api.model
def default_view(self, model, view_type):
""" Fetches the default view for the provided (model, view_type) pair:
primary view with the lowest priority.
:param str model:
:param int view_type:
:return: id of the default view of False if none found
:rtype: int
"""
domain = [('model', '=', model), ('type', '=', view_type), ('mode', '=', 'primary')]
return self.search(domain, limit=1).id

有点坑啊,大家在视图继承的时候。权重基本上是默认的,也就是说若不考虑name的影响,那么默认视图将永远是最先添加的基础视图。但是,这里name的排序居然还在ID的前面,这就有的玩了嘛,起名字也是门艺术了。
read_combined函数拼接出来以基础视图为框架,包含所有继承视图内容的etree对象。
def read_combined(self, fields=None):
"""
Utility function to get a view combined with its inherited views.
* Gets the top of the view tree if a sub-view is requested
* Applies all inherited archs on the root view
* Returns the view with all requested fields
.. note:: ``arch`` is always added to the fields list even if not
requested (similar to ``id``)
"""
# introduce check_view_ids in context
if 'check_view_ids' not in self._context:
self = self.with_context(check_view_ids=[])
check_view_ids = self._context['check_view_ids']
# if view_id is not a root view, climb back to the top.
root = self
while root.mode != 'primary':
# Add inherited views to the list of loading forced views
# Otherwise, inherited views could not find elements created in their direct parents if that parent is defined in the same module
check_view_ids.append(root.id)
root = root.inherit_id
# arch and model fields are always returned
if fields:
fields = list({'arch', 'model'}.union(fields))
# read the view arch
[view_data] = root.read(fields=fields)
view_arch = etree.fromstring(view_data['arch'].encode('utf-8'))
if not root.inherit_id:
if self._context.get('inherit_branding'):
view_arch.attrib.update({
'data-oe-model': 'ir.ui.view',
'data-oe-id': str(root.id),
'data-oe-field': 'arch',
})
arch_tree = view_arch
else:
if self._context.get('inherit_branding'):
root.inherit_branding(view_arch)
parent_view = root.inherit_id.read_combined(fields=fields)
arch_tree = etree.fromstring(parent_view['arch'])
arch_tree = self.browse(parent_view['id']).apply_inheritance_specs(arch_tree, view_arch)
# and apply inheritance
arch = root.apply_view_inheritance(arch_tree, self.model)
return dict(view_data, arch=etree.tostring(arch, encoding='unicode'))
结束
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
在我的系统中,我已经定义了STI。Dog继承自Animal,在animals表中有一个type列,其值为"Dog"。现在我想让SpecialDog继承自dog,只是为了在某些特殊情况下稍微修改一下行为。数据还是一样。我需要通过SpecialDog运行的所有查询,以返回数据库中类型为Dog的值。我的问题是因为我有一个type列,rails将WHERE"animals"."type"IN('SpecialDog')附加到我的查询中,所以我不能获取原始的Dog条目。所以我想要的是以某种方式覆盖rails在通过SpecialDog访问数据库时使用的值,使其表现得像Dog。有没有办法覆盖用于类型
我看到其他人也遇到过类似的问题,但没有一个解决方案对我有用。0.3.14gem与其他gem文件一起存在。我已经完全按照此处指示完成了所有操作:https://github.com/brianmario/mysql2.我仍然得到以下信息。我不知道为什么安装程序指示它找不到include目录,因为我已经检查过它存在。thread.h文件存在,但不在ruby目录中。相反,它在这里:C:\RailsInstaller\DevKit\lib\perl5\5.8\msys\CORE\我正在运行Windows7并尝试在Aptana3中构建我的Rails项目。我的Ruby是1.9.3。$gemin
我试图在Ubuntu14.04中使用Curl安装RVM。我运行了以下命令:\curl-sSLhttps://get.rvm.io|bash-sstable出现如下错误:curl:(7)Failedtoconnecttoget.rvm.ioport80:Networkisunreachable非常感谢解决此问题的任何帮助。谢谢 最佳答案 在执行curl之前尝试这个:echoipv4>>~/.curlrc 关于ruby-在Ubuntu14.04中使用Curl安装RVM时出错,我们在Stack
所以我只是对此感到好奇:DataMapper为其模型使用混合classPostincludeDataMapper::Resource虽然active-record使用继承classPost有谁知道为什么DataMapper选择这样做(或者为什么AR选择不这样做)? 最佳答案 它允许您从另一个不是DM类的类继承。它还允许动态地将DM功能添加到类中。这是我正在处理的模块中的类方法:defdatamapper_classklass=self.dupklass.send(:include,DataMapper::Resource)klass
我使用RVM安装Ruby-2.1.5并再次运行bundle。现在pggem不会安装,我得到这个错误:geminstallpg-v'0.17.1'----with-pg-config=/Applications/Postgres.app/Contents/Versions/9.3/bin/pg_configBuildingnativeextensionswith:'--with-pg-config=/Applications/Postgres.app/Contents/Versions/9.3/bin/pg_config'Thiscouldtakeawhile...ERROR:Error
我正在使用带有单个“帐户”表的STI模型来保存用户和技术人员的信息(即用户...8)错误:test_the_truth(用户测试):ActiveRecord::StatementInvalid:PGError:ERROR:关系“技术人员”不存在:从“技术人员”中删除...从本质上讲,标准框架不承认Technicians和Users表(或PostgreSQL称它们为“关系”)不存在,事实上,应该别名为Accounts。有什么想法吗?我对RoR比较陌生,不知道如何解决这个问题而又不完全删除STI。 最佳答案 原来问题是由于存在:./te
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我最近开始学习Ruby,这是我的第一门编程语言。我对语法感到满意,并且我已经完成了许多只教授相同基础知识的教程。我已经写了一些小程序(包括我自己的数组排序方法,在有人告诉我谷歌“冒泡排序”之前我认为它非常聪明),但我觉得我需要尝试更大更难的东西来理解更多关于Ruby.关于如何执行此操作的任何想法?
假设我有一个名为Flight的模块,其中包含类方法和实例方法。我可以使用include、extend或两者将其方法放入类中:classBatinclude会将Flight添加到Bat.ancestors,但extend不会。我的问题是,为什么模块与类不同?当我对Mammal进行子类化时,我总是同时获得类和实例方法。然而,当我混入一个模块时,我不能同时获得类和实例方法(除非我使用self.included钩子(Hook)或类似ActiveSupport::Concern的东西)。这种差异背后是否存在语言设计问题? 最佳答案 Modul
安装Rails时,一切都很好,但后来,我写道:rails-v和输出:/home/toshiba/.rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in`require':cannotloadsuchfile--rails/cli(LoadError)from/home/toshiba/.rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in`r