Odoo - 为附件实施标签系统

Odoo - Implementing a tag system for attachments

有人要求我为 Odoo 中的附件开发一个标签系统。

虽然我找到了 this standard module(称为文档管理系统)附件,但我没有找到任何对标签管理有用的东西。

因此,我开发了自己的自定义模块,其中附件(由核心 ir.attachment 模型表示)已通过与 tag 模型的 Many2many 关系进行了扩展,反过来代表...一个标签,并且有一个 tag 字段代表实际标签的文本内容。

然后我一直在努力按标签搜索...

Odoo 搜索视图基于 A OP B 表达式,其中 A 是模型字段,OP 是运算符(例如 =),B (通常)是搜索词(但它可以是任何 Python 表达式)。

这里的问题是搜索词必须与相关对象的字段(即标签)进行比较,与附件本身的字段。

所以我想出了一个解决方法。我扩展了附件模型:

每次执行搜索时都会调用

_search_tags,其工作是根据搜索的词将标志 found_by_tag 设置为正确的值。

因此,搜索视图的表达式变为 [('found_by_tag', '=', True)]

这是 Python 代码的相关部分:

# Attachments
class attachment(models.Model):
 _inherit = 'ir.attachment'

 # Tag management
 tag_ids = fields.Many2many('attachmentssample.tag', string = 'Tags')
 tags = fields.Text(compute = '_compute_tags', search = '_search_tags')
 found_by_tag = fields.Boolean()

 @api.one
 @api.depends('tag_ids')
 def _compute_tags(self):
  tags = ''
  for tag in self.tag_ids:
   tags += tag.tag + ','
  self.tags = tags

 def _search_tags(self, operator, value):
  attachments = self.search([])
  for attachment in attachments:
   attachment.checkIfRelevantFor(value)
  return [('found_by_tag', '=', True)]

 def checkIfRelevantFor(self, search_tag):
  relevant = False
  for tag in self.tag_ids:
   if tag.tag == search_tag:
    relevant = True
  if relevant:
   self.found_by_tag = True
  else:
   self.found_by_tag = False

# Tags
class tag(models.Model):
 _name = 'attachmentssample.tag'

 tag = fields.Char()

虽然解决方法确实有效,但我想知道这是否太多了。有没有更简单的方法来实现按标签搜索?或者,是否有可用于此目的的模块?

不确定社区中是否存在此模块,

但理想情况下,从 odoo 实施指南来看,您所做的是完全正确的。如果您认为要提高 css 样式和可重用性因素,则需要为标签使用额外的模型。你会在 v9 中看到这些东西已经完成

再三考虑,如果您认为这些标签只是提供信息,那么您可以制作文本字段并存储以逗号分隔的值,并且您的辅助方法可以轻松地用逗号拆分或连接。为什么会有这个想法。因为这将大大减少每次阅读附件时标签的数据库 IO 以及 ir.attachment 链接到所有模型记录的事实,总的来说,消除 table 对性能有好处,因为 python 代码是比 db IO 快得多。

最好成绩

我想出了可能的最佳解决方案。在 Odoo Development Essentials 一书中解释说,当 left-hand 端是 "to-many" 字段时,域表达式中的 'in' 运算符的行为不同。在这种情况下,('A', 'in', B) 的语义变为 "keep the record with id B if B is one of the ids of the records referenced by A"。换句话说,表达式应该反过来读。有了这些知识,您可以分两步实现标签搜索:

  1. 查找与当前查询匹配的标签。
  2. 在像 ('attachment_ids', 'in', id).
  3. 这样的域表达式中使用它的 id

使用此策略,您不需要额外的字段来支持搜索。

(伙计……Odoo 开发是……具有挑战性的)