Odoo10開發(fā)教程八(向?qū)c國際化)

向?qū)?/h4>

向?qū)б詣討B(tài)形式描述與用戶(或?qū)υ捒颍┑慕换ナ綍挕O驅(qū)c其他的模型不同,其基類是TransientModel而不是常見的ModelTransientModel類擴展自Model,并使用了其所有機制,具有以下特殊性:

  • 向?qū)в涗洸皇怯谰眯缘模瑫谝欢螘r間后自動從數(shù)據(jù)庫中刪除。這就是為什么他們被稱為瞬態(tài)
  • 向?qū)P筒恍枰L問權(quán)限:用戶擁有向?qū)в涗浀乃袡?quán)限
  • 向?qū)в涗浛梢酝ㄟ^many2one字段引用普通記錄或向?qū)в涗洠胀ㄓ涗洘o法通過many2one引用向?qū)в涗洝?br> 我們要創(chuàng)建一個向?qū)В脕碜層脩艨梢陨墒谡n的參與者,或者一次創(chuàng)建一個授課列表。

練習(xí)定義向?qū)?br> 創(chuàng)建一個向?qū)P停@個向?qū)P屯ㄟ^many2one關(guān)聯(lián)授課模型,并通過many2many關(guān)聯(lián)合作伙伴模型。添加新文件openacademy/wizard.py

openacademy/__init__.py

from . import controllers
from . import models
from . import partner
from . import wizard

openacademy/wizard.py

# -*- coding: utf-8 -*-

from odoo import models, fields, api

class Wizard(models.TransientModel):
    _name = 'openacademy.wizard'

    session_id = fields.Many2one('openacademy.session',
        string="Session", required=True)
    attendee_ids = fields.Many2many('res.partner', string="Attendees")

啟動向?qū)?/h5>

向?qū)ㄟ^ir.actions.act_window記錄來啟動,target字段設(shè)置值為new。后者將在一個彈出窗口中打開向?qū)А2僮骺梢杂胁藛雾椨|發(fā)。還有另外一種方式來啟動向?qū)В菏褂妙愃朴谏厦娴?code>ir.actions.act_window記錄,但有一個額外字段src_model,指定那個模型的操作可用。該向?qū)⒊霈F(xiàn)在模型主視圖的上下文操作中。因為這是在ORM中的內(nèi)部鉤子,所以這個操作通過在XML文件的act_window標(biāo)簽中進行定義。

<act_window id="launch_the_wizard"
            name="Launch the Wizard"
            src_model="context.model.name"
            res_model="wizard.model.name"
            view_mode="form"
            target="new"
            key2="client_action_multi"/>

向?qū)褂贸R?guī)視圖并且它的按鈕可以使用special="cancel"來關(guān)閉向?qū)Т翱诙恍枰3帧?/p>

練習(xí)啟動向?qū)?/p>

  1. 為向?qū)Фx一個form視圖
  2. 在授課模型的上下文中添加action用于啟動向?qū)?/li>
  3. 給向?qū)У?em>session字段定義默認值;使用上下文參數(shù)self._context來獲取當(dāng)前授課

openacademy/wizard.py

class Wizard(models.TransientModel):
    _name = 'openacademy.wizard'

    def _default_session(self):
        return self.env['openacademy.session'].browse(self._context.get('active_id'))

    session_id = fields.Many2one('openacademy.session',
        string="Session", required=True, default=_default_session)
    attendee_ids = fields.Many2many('res.partner', string="Attendees")

openacademy/views/openacademy.xml

                  parent="openacademy_menu"
                  action="session_list_action"/>

        <record model="ir.ui.view" id="wizard_form_view">
            <field name="name">wizard.form</field>
            <field name="model">openacademy.wizard</field>
            <field name="arch" type="xml">
                <form string="Add Attendees">
                    <group>
                        <field name="session_id"/>
                        <field name="attendee_ids"/>
                    </group>
                </form>
            </field>
        </record>

        <act_window id="launch_session_wizard"
                    name="Add Attendees"
                    src_model="openacademy.session"
                    res_model="openacademy.wizard"
                    view_mode="form"
                    target="new"
                    key2="client_action_multi"/>
    </data>
</odoo>

練習(xí)注冊與會者
給向?qū)砑影粹o,并且實現(xiàn)相應(yīng)的方法,將與會者添加到給定的授課。

openacademy / views / openacademy.xml

                        <field name="attendee_ids"/>
                    </group>
                    <footer>
                        <button name="subscribe" type="object"
                                string="Subscribe" class="oe_highlight"/>
                        or
                        <button special="cancel" string="Cancel"/>
                    </footer>
                </form>
            </field>
        </record>

openacademy/wizard.py

    session_id = fields.Many2one('openacademy.session',
        string="Session", required=True, default=_default_session)
    attendee_ids = fields.Many2many('res.partner', string="Attendees")

    @api.multi
    def subscribe(self):
        self.session_id.attendee_ids |= self.attendee_ids
        return {}

練習(xí)與會者注冊多個授課
修改向?qū)P停员闩c會者可以注冊到多個授課

openacademy/views/openacademy.xml

                <form string="Add Attendees">
                    <group>
                        <field name="session_ids"/>
                        <field name="attendee_ids"/>
                    </group>
                    <footer>
                        <button name="subscribe" type="object"

openacademy/wizard.py

class Wizard(models.TransientModel):
    _name = 'openacademy.wizard'

    def _default_sessions(self):
        return self.env['openacademy.session'].browse(self._context.get('active_ids'))

    session_ids = fields.Many2many('openacademy.session',
        string="Sessions", required=True, default=_default_sessions)
    attendee_ids = fields.Many2many('res.partner', string="Attendees")

    @api.multi
    def subscribe(self):
        for session in self.session_ids:
            session.attendee_ids |= self.attendee_ids
        return {}

國際化

每個模塊都可以在i18n目錄提供自己的翻譯,文件名的形式為LANG.po,其中LANG是語言的代碼,或者是語言和國家的組合,例如:pt.po(葡萄牙語)和pt_BR.po(巴西葡萄牙語)。對于所有開啟的語言,Odoo都會自動載入翻譯。開發(fā)者總是使用英語建立模塊,然后使用Odoo的文本POT導(dǎo)出功能導(dǎo)出模塊術(shù)語(設(shè)置->翻譯->導(dǎo)入/導(dǎo)出->導(dǎo)出翻譯),生成模塊的POT模板文件,然后到處PO翻譯文件。許多IDE具有用于編輯和合并PO/POT文件的插件或功能。

提示
把Odoo生成的導(dǎo)出文件公布在Transifex,可以輕松的使用軟件進行翻譯。

|- idea/ # The module directory
   |- i18n/ # Translation files
      | - idea.pot # Translation Template (exported from Odoo)
      | - fr.po # French translation
      | - pt_BR.po # Brazilian Portuguese translation
      | (...)

提示
默認情況下Odoo的POT導(dǎo)出僅提取XML文件的標(biāo)簽和Python代碼中的字段定義,但是任何Python字符串都可以翻譯,通過使用odoo._()方法,例如_("Label")


練習(xí)
翻譯一個模塊
為已經(jīng)安裝的Odoo模塊選擇第二語言。使用Odoo提供的功能對模塊進行翻譯。

  1. 創(chuàng)建目錄openacademy/i18n/
  2. 安裝任意一種你希望的語言 (設(shè)置->翻譯->加載翻譯
  3. 同步翻譯術(shù)語(設(shè)置->翻譯->應(yīng)用程序術(shù)語->同步術(shù)語
  4. 導(dǎo)出不指定語言的翻譯模板文件(設(shè)置->翻譯->導(dǎo)入/導(dǎo)出->導(dǎo)出翻譯),保存在openacademy/i18n/
  5. 導(dǎo)出指定語言的翻譯文件(設(shè)置->翻譯->導(dǎo)入/導(dǎo)出->導(dǎo)出翻譯),保存在openacademy/i18n/
  6. 打開導(dǎo)出的翻譯文件(使用任意一款文本編輯軟件或者專用的PO文件編輯器,例如POEdit然后翻譯其中的術(shù)語)
  7. models.py文件中,為odoo._方法添加一個導(dǎo)入聲明,并且標(biāo)記需要翻譯的字符串
  8. 重復(fù)3-6的步驟

openacademy/models.py

# -*- coding: utf-8 -*-

from datetime import timedelta
from odoo import models, fields, api, exceptions, _

class Course(models.Model):
    _name = 'openacademy.course'
        default = dict(default or {})

        copied_count = self.search_count(
            [('name', '=like', _(u"Copy of {}%").format(self.name))])
        if not copied_count:
            new_name = _(u"Copy of {}").format(self.name)
        else:
            new_name = _(u"Copy of {} ({})").format(self.name, copied_count)

        default['name'] = new_name
        return super(Course, self).copy(default)
        if self.seats < 0:
            return {
                'warning': {
                    'title': _("Incorrect 'seats' value"),
                    'message': _("The number of available seats may not be negative"),
                },
            }
        if self.seats < len(self.attendee_ids):
            return {
                'warning': {
                    'title': _("Too many attendees"),
                    'message': _("Increase seats or remove excess attendees"),
                },
            }
    def _check_instructor_not_in_attendees(self):
        for r in self:
            if r.instructor_id and r.instructor_id in r.attendee_ids:
                raise exceptions.ValidationError(_("A session's instructor can't be an attendee"))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,321評論 6 543
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,559評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,442評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,835評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,581評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,922評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,931評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,096評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,639評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,374評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,591評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,104評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,789評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,196評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,524評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,322評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,554評論 2 379

推薦閱讀更多精彩內(nèi)容