我想从 python 代码创建附件。
所以,我尝试过:
self.env['ir.attachment'].create({
'store_fname' : ??,
'checksum' : ??
})
应该为 ir_attachment 表中的“store_fname”和“checksum”列传递什么值?
这些字段应自动填写:
store_fname
是文件夹以及文件存储在 filestore 文件夹中时使用的名称checksum
也与文件名一致。就是对文件数据应用sha1算法的结果数据库中的示例:
id | store_fname | checksum
-----+---------------------------------------------+------------------------------------------
1 | fc/fc78476ab1658bfedda7dde9b515d1c705472c1f | fc78476ab1658bfedda7dde9b515d1c705472c1f
2 | 97/97d5689a6bd71e33f9439f8235d54855a69134f3 | 97d5689a6bd71e33f9439f8235d54855a69134f3
348 | 54/549f82ae56b7397db7fcd8ca1a179494b0cfda03 | 549f82ae56b7397db7fcd8ca1a179494b0cfda03
看看它们是如何计算的:
@api.depends('store_fname', 'db_datas')
def _compute_datas(self):
bin_size = self._context.get('bin_size')
for attach in self:
if attach.store_fname:
attach.datas = self._file_read(attach.store_fname, bin_size)
else:
attach.datas = attach.db_datas
def _inverse_datas(self):
location = self._storage()
for attach in self:
# compute the fields that depend on datas
value = attach.datas
bin_data = base64.b64decode(value) if value else b''
vals = {
'file_size': len(bin_data),
'checksum': self._compute_checksum(bin_data),
'index_content': self._index(bin_data, attach.datas_fname, attach.mimetype),
'store_fname': False,
'db_datas': value,
}
if value and location != 'db':
# save it to the filestore
vals['store_fname'] = self._file_write(value, vals['checksum'])
vals['db_datas'] = False
# take current location in filestore to possibly garbage-collect it
fname = attach.store_fname
# write as superuser, as user probably does not have write access
super(IrAttachment, attach.sudo()).write(vals)
if fname:
self._file_delete(fname)
def _compute_checksum(self, bin_data):
""" compute the checksum for the given datas
:param bin_data : datas in its binary form
"""
# an empty file has a checksum too (for caching)
return hashlib.sha1(bin_data or b'').hexdigest()
# the field 'datas' is computed and may use the other fields below
datas = fields.Binary(
string='File Content',
compute='_compute_datas',
inverse='_inverse_datas'
)
如何创建附件的示例取自 BaseImportImport:
@api.model
@api.returns('ir.attachment')
def _create_csv_attachment(self, fields, data, options, file_name):
# write csv
f = StringIO()
writer = csv.writer(f,
delimiter=str(options.get(OPT_SEPARATOR)),
quotechar=str(options.get(OPT_QUOTING)))
encoding = options.get(OPT_ENCODING, 'utf-8')
writer.writerow(fields)
for row in data:
writer.writerow(row)
# create attachment
datas = base64.encodebytes(f.getvalue().encode(encoding))
attachment = self.env['ir.attachment'].create({
'name': file_name,
'datas': datas,
'datas_fname': file_name
})
return attachment
尽管如果您想将附件链接到某些模型中的某些记录,字段
res_id
和 res_model
也很有用
id | store_fname | checksum | res_model | res_id
-----+---------------------------------------------+------------------------------------------+------------------+--------
1 | fc/fc78476ab1658bfedda7dde9b515d1c705472c1f | fc78476ab1658bfedda7dde9b515d1c705472c1f | res.country | 1
2 | 97/97d5689a6bd71e33f9439f8235d54855a69134f3 | 97d5689a6bd71e33f9439f8235d54855a69134f3 | res.country | 2
348 | 54/549f82ae56b7397db7fcd8ca1a179494b0cfda03 | 549f82ae56b7397db7fcd8ca1a179494b0cfda03 | ir.ui.menu | 77
3 | c5/c5fd52fe3cf431f70c6d778c555f027c97a0ac09 | c5fd52fe3cf431f70c6d778c555f027c97a0ac09 | res.country | 3
对于我来说,我想在我的API路由中获取base64二进制图像。我无法获取图像,任何人都知道我怎样才能获得产品图像的真正base64字符串
这是 mysql 查询其
SELECT jsonb_build_object(
'id', pt.id,
'product_variant_ids',
(
SELECT jsonb_agg(jsonb_build_object('id', pp.id, 'name', pt.name->> 'en_US'))
FROM product_product pp
WHERE pp.product_tmpl_id = pt.id
),
'name', pt.name->> 'en_US',
'categ_id',
(
SELECT jsonb_agg(jsonb_build_object('id', pc.id, 'name', pc.name))
FROM product_category pc
WHERE pt.categ_id = pc.id
),
'image_1920',
(
SELECT jsonb_agg(jsonb_build_object('id', ia.id, 'file_name', ia.name, 'datas', ia.store_fname))
FROM ir_attachment ia
WHERE ia.res_model = 'product.template'
AND ia.res_field = 'image_1920'
AND ia.res_id = pt.id
)
)
FROM product_template pt
JOIN product_category pc ON pt.categ_id = pc.id
WHERE pt.active = true
AND pc.complete_name LIKE '%All%'
AND (pt.name ->> 'en_US' ILIKE '%code%'
OR (regexp_replace(pt.name ->> 'en_US', '[^a-zA-Z0-9]', '', 'g')) ILIKE 'code%')
GROUP BY pt.id, pt.name
ORDER BY CASE WHEN (pt.name ->> 'en_US' ILIKE 'code%'
OR (regexp_replace(pt.name ->> 'en_US', '[^a-zA-Z0-9]', '', 'g')) ILIKE 'code%') THEN 1 ELSE 2 END, pt.name ->> 'en_US'; ```
and here is my python code for its
```python3
search = request.httprequest.values.get('search', None)
sql = """
SELECT jsonb_build_object(
'id', pt.id,
'product_variant_ids',
(
SELECT jsonb_agg(jsonb_build_object('id', pp.id, 'name', pt.name->> 'en_US'))
FROM product_product pp
WHERE pp.product_tmpl_id = pt.id
),
'name', pt.name->> 'en_US',
'categ_id',
(
SELECT jsonb_agg(jsonb_build_object('id', pc.id, 'name', pc.name))
FROM product_category pc
WHERE pt.categ_id = pc.id
),
'image_1920',
(
SELECT jsonb_agg(jsonb_build_object('id', ia.id, 'file_name', ia.name))
FROM ir_attachment ia
WHERE ia.res_model = 'product.template'
AND ia.res_field = 'image_1920'
AND ia.res_id = pt.id
)
)
FROM product_template pt
JOIN product_category pc ON pt.categ_id = pc.id
WHERE pt.active = true
AND pc.complete_name LIKE '%All%'
AND (pt.name ->> 'en_US' ILIKE '%{}%'
OR (regexp_replace(pt.name ->> 'en_US', '[^a-zA-Z0-9]', '', 'g')) ILIKE '{}%')
GROUP BY pt.id, pt.name
ORDER BY CASE WHEN (pt.name ->> 'en_US' ILIKE '{}%'
OR (regexp_replace(pt.name ->> 'en_US', '[^a-zA-Z0-9]', '', 'g')) ILIKE '{}%') THEN 1 ELSE 2 END, pt.name ->> 'en_US';
""".format(search, search, search, search)
request.cr.execute(sql)
data = request.cr.fetchall()
print(data)