[FIX] base_multi_image - New storage backend 'Filestore' to link an existing attachment record + Fix the 'pre_init_hook_for_submodules()' hook to extract the images from the ir_attachment table for binary fields initialized with the 'attachment=True' parameter
parent
3d52d71442
commit
7e17b85e9a
|
@ -22,23 +22,44 @@ def pre_init_hook_for_submodules(cr, model, field):
|
||||||
"""
|
"""
|
||||||
env = api.Environment(cr, SUPERUSER_ID, dict())
|
env = api.Environment(cr, SUPERUSER_ID, dict())
|
||||||
with cr.savepoint():
|
with cr.savepoint():
|
||||||
|
table = env[model]._table
|
||||||
|
column_exists = table_has_column(cr, table, field)
|
||||||
|
# Extract the binary content directly from the table
|
||||||
|
if column_exists:
|
||||||
|
extract_query = """
|
||||||
|
SELECT id, %%s, 'db', %(field)s
|
||||||
|
FROM %(table)s
|
||||||
|
WHERE %(field)s IS NOT NULL
|
||||||
|
""" % {"table": table, "field": field}
|
||||||
|
image_field = 'file_db_store'
|
||||||
|
# Extract the binary content from the ir_attachment table
|
||||||
|
else:
|
||||||
|
extract_query = """
|
||||||
|
SELECT res_id, res_model, 'filestore', id
|
||||||
|
FROM ir_attachment
|
||||||
|
WHERE res_field='%(field)s' AND res_model='%(model)s'
|
||||||
|
""" % {"model": model, "field": field}
|
||||||
|
image_field = 'attachment_id'
|
||||||
|
|
||||||
|
cr.execute(extract_query)
|
||||||
cr.execute(
|
cr.execute(
|
||||||
"""
|
"""
|
||||||
INSERT INTO base_multi_image_image (
|
INSERT INTO base_multi_image_image (
|
||||||
owner_id,
|
owner_id,
|
||||||
owner_model,
|
owner_model,
|
||||||
storage,
|
storage,
|
||||||
file_db_store
|
%s
|
||||||
)
|
)
|
||||||
SELECT
|
%s
|
||||||
id,
|
""" % (image_field, extract_query)
|
||||||
%%s,
|
|
||||||
'db',
|
|
||||||
%(field)s
|
|
||||||
FROM
|
|
||||||
%(table)s
|
|
||||||
WHERE
|
|
||||||
%(field)s IS NOT NULL
|
|
||||||
""" % {"table": env[model]._table, "field": field},
|
|
||||||
(model,)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def table_has_column(cr, table, field):
|
||||||
|
query = """
|
||||||
|
SELECT %(field)s
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_name=%(table)s and column_name=%(field)s;
|
||||||
|
"""
|
||||||
|
cr.execute(query, {'table': table, 'field': field})
|
||||||
|
return bool(cr.fetchall())
|
||||||
|
|
|
@ -28,7 +28,8 @@ class Image(models.Model):
|
||||||
owner_model = fields.Char(
|
owner_model = fields.Char(
|
||||||
required=True)
|
required=True)
|
||||||
storage = fields.Selection(
|
storage = fields.Selection(
|
||||||
[('url', 'URL'), ('file', 'OS file'), ('db', 'Database')],
|
[('url', 'URL'), ('file', 'OS file'), ('db', 'Database'),
|
||||||
|
('filestore', 'Filestore')],
|
||||||
required=True)
|
required=True)
|
||||||
name = fields.Char(
|
name = fields.Char(
|
||||||
'Image title',
|
'Image title',
|
||||||
|
@ -37,6 +38,9 @@ class Image(models.Model):
|
||||||
extension = fields.Char(
|
extension = fields.Char(
|
||||||
'File extension',
|
'File extension',
|
||||||
readonly=True)
|
readonly=True)
|
||||||
|
attachment_id = fields.Many2one(
|
||||||
|
'ir.attachment',
|
||||||
|
string='Attachment')
|
||||||
file_db_store = fields.Binary(
|
file_db_store = fields.Binary(
|
||||||
'Image stored in database',
|
'Image stored in database',
|
||||||
filters='*.png,*.jpg,*.gif')
|
filters='*.png,*.jpg,*.gif')
|
||||||
|
@ -84,6 +88,10 @@ class Image(models.Model):
|
||||||
"default_owner_%s" % f not in self.env.context
|
"default_owner_%s" % f not in self.env.context
|
||||||
for f in ("id", "model"))
|
for f in ("id", "model"))
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def _get_image_from_filestore(self):
|
||||||
|
return self.attachment_id.datas
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def _get_image_from_db(self):
|
def _get_image_from_db(self):
|
||||||
return self.file_db_store
|
return self.file_db_store
|
||||||
|
@ -157,6 +165,11 @@ class Image(models.Model):
|
||||||
self.name, self.extension = os.path.splitext(self.filename)
|
self.name, self.extension = os.path.splitext(self.filename)
|
||||||
self.name = self._make_name_pretty(self.name)
|
self.name = self._make_name_pretty(self.name)
|
||||||
|
|
||||||
|
@api.onchange('attachment_id')
|
||||||
|
def _onchange_attachmend_id(self):
|
||||||
|
if self.attachment_id:
|
||||||
|
self.name = self.attachment_id.res_name
|
||||||
|
|
||||||
@api.constrains('storage', 'url')
|
@api.constrains('storage', 'url')
|
||||||
def _check_url(self):
|
def _check_url(self):
|
||||||
if self.storage == 'url' and not self.url:
|
if self.storage == 'url' and not self.url:
|
||||||
|
@ -174,3 +187,9 @@ class Image(models.Model):
|
||||||
if self.storage == 'db' and not self.file_db_store:
|
if self.storage == 'db' and not self.file_db_store:
|
||||||
raise exceptions.ValidationError(
|
raise exceptions.ValidationError(
|
||||||
'You must provide an attached file for the image.')
|
'You must provide an attached file for the image.')
|
||||||
|
|
||||||
|
@api.constrains('storage', 'attachment_id')
|
||||||
|
def _check_store(self):
|
||||||
|
if self.storage == 'filestore' and not self.attachment_id:
|
||||||
|
raise exceptions.ValidationError(
|
||||||
|
'You must provide an attachment for the image.')
|
||||||
|
|
|
@ -50,6 +50,12 @@
|
||||||
'required': [('storage', '=', 'db')],
|
'required': [('storage', '=', 'db')],
|
||||||
}"
|
}"
|
||||||
filename="filename"/>
|
filename="filename"/>
|
||||||
|
<field
|
||||||
|
name="attachment_id"
|
||||||
|
attrs="{
|
||||||
|
'invisible': [('storage', '!=', 'filestore')],
|
||||||
|
'required': [('storage', '=', 'filestore')],
|
||||||
|
}"/>
|
||||||
</group>
|
</group>
|
||||||
<group string="Preview">
|
<group string="Preview">
|
||||||
<field name="image_medium"
|
<field name="image_medium"
|
||||||
|
|
Loading…
Reference in New Issue