I've been asked to develop a tag system for attachments in Odoo.
While for attachments I've found this standard module (called Document Management System), I didn't find anything useful for tag management.
Thus, I've developed my own, custom module in which attachments (represented by the core ir.attachment
model) have been extended with a Many2many relation with a tag
model, that in turn represents... a tag, and has a tag
field representing the actual tag's textual content.
Then I've been struggling with search by tag...
Odoo search views are based on A OP B
expressions where A
is a model's field, OP
is an operator (e.g. =
) and B
(usually) is the searched term (but it can be any Python expression).
The problem here is that the searched term has to be compared with a related object's fields (i.e. the tags), not with a field of the attachment itself.
So I came up with a workaround. I've extended the attachment model with:
- a computed char field called
tags
with an associated custom search method_search_tags
- a boolean field called
found_by_tag
_search_tags
is invoked each time a search is performed and its job is to set the flag found_by_tag
to the proper value, based on the searched term.
Thus, the expression for the search view becomes [('found_by_tag', '=', True)]
.
That's the relevant part from the Python code:
# 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()
While the workaround actually works, I'm wondering if that's too much. Is there a simpler way to implement a search by tag? Or, alternatively, is there a module that may be used for this purpose?