使用 Odoo 的時(shí)候,經(jīng)常會有導(dǎo)出數(shù)據(jù)的需要。默認(rèn)的導(dǎo)出往往不是我們想要的,比如導(dǎo)出 many2many tags,或者導(dǎo)出去掉 HTML 格式標(biāo)簽的內(nèi)容。
一般來說需要重載 export_data 這個(gè)model 的方法。
@api.multi
def export_data(self, fields_to_export, raw_data=False):
假若 model 類中有 category field,是一個(gè) many2many 的 tag,如果使用默認(rèn)的 Odoo 導(dǎo)出,支持兩種模式,一種是更新數(shù)據(jù)兼容導(dǎo)入(import compatible),一種是電子表格中使用數(shù)據(jù)導(dǎo)出。

如果使用更新兼兼容方式 many2many 會被正確處理(我們想要的正確處理,對這個(gè) Odoo 一定是有不同的理解)成一個(gè)字符串列表,中間逗號分開,但是這種導(dǎo)出模式的是為了再次導(dǎo)入做準(zhǔn)備,所以數(shù)據(jù) Head 都是字段名稱,閱讀起來非常不友好;如果電子表格中使用數(shù)據(jù)模式導(dǎo)出,就會把每個(gè) many2many 的數(shù)據(jù)單獨(dú)導(dǎo)出成一條記錄,字段名稱都是可以理解閱讀的名稱,記錄中有多少 category tag 就會把一條記錄變成 N 條,當(dāng)然 N - 1 條中除了 category 這個(gè)字段外其他都是空的。這兩種模式都不太符合需要,我們即需要可以理解的 Head 也需要把 many2many tags 放到一起。通過查看 model 的代碼可以看到:
import_compatible = self.env.context.get('import_compat', True)
...
# in import_compat mode, m2m should always be exported
# a comma-separated list of xids in a single cell
if import_compatible and field.type == 'many2many' and len(path) > 1 and path[1] == 'id':
xml_ids = [xid for _, xid in value.__ensure_xml_id()]
current[i] = ','.join(xml_ids) or False
continue
就是說只要 import compatible (導(dǎo)入兼容)那么就用逗號拼接返回 many2many 的值。確實(shí)和我們測試的一樣,于是:
@api.multi
def export_data(self, fields_to_export, raw_data=False):
self = self.with_context(import_compat=True)
res = super().export_data(fields_to_export, raw_data)
return res
通過改一下 context 的信息,臨時(shí)應(yīng)用一下 import compatible,經(jīng)過測試可以。
其實(shí)這個(gè)事情還沒有完,因?yàn)閷?dǎo)出的 category tags 還是 id,不是 category 表中的 display name 或者 name 字段,這需要進(jìn)一步做工作。
@api.multi
def export_data(self, fields_to_export, raw_data=False):
self = self.with_context(import_compat=True)
res = super().export_data(fields_to_export, raw_data)
fields_name = dict(zip(fields_to_export,range(len(fields_to_export))))
field_index = fields_name.get("category_id/id")
if field_index == None:
return
for index, val in enumerate(res['datas']):
cat_field = res['datas'][index][field_index]
new_cats = []
...
res['datas'][index][field_index] = ",".join(new_cats)
return
構(gòu)造了新的 category 之后把原來的內(nèi)容替換掉。
如果想把 Html 中的格式標(biāo)簽去掉可以用一個(gè)正則表達(dá)式:
plain_text = re.sub('<.*?>',"",html_field)
res['datas'][index][field_index] = plain_text.strip()
這樣我們就能在 Odoo 導(dǎo)出功能的基礎(chǔ)上對表、字段進(jìn)行自己的處理,還不用修改 Odoo 本身的代碼。Bing Go!