混合類和有用的類?
Odoo 實現了一些有用的類和 mixin,使您可以輕松地在對象上添加經常使用的行為。本指南將詳細介紹其中大部分,包括示例和用例。
消息功能?
消息集成?
基本消息系統?
將消息功能集成到您的模型非常容易。只需繼承 mail.thread
模型并將消息字段(及其適當的小部件)添加到您的表單視圖中,即可立即運行。
Example
讓我們創建一個簡單的模型來代表商務旅行。由于組織這種旅行通常涉及到很多人和很多討論,因此讓我們在模型上添加消息交換的支持。
class BusinessTrip(models.Model):
_name = 'business.trip'
_inherit = ['mail.thread']
_description = 'Business Trip'
name = fields.Char()
partner_id = fields.Many2one('res.partner', 'Responsible')
guest_ids = fields.Many2many('res.partner', 'Participants')
在表單視圖中:
<record id="businness_trip_form" model="ir.ui.view">
<field name="name">business.trip.form</field>
<field name="model">business.trip</field>
<field name="arch" type="xml">
<form string="Business Trip">
<!-- Your usual form view goes here
...
Then comes chatter integration -->
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
一旦您在您的模型上添加了聊天支持,用戶可以輕松地在您模型的任何記錄上添加消息或內部備注;每個消息都會發送通知(對于消息,發送給所有關注者,對于內部備注,發送給員工( base.group_user )用戶)。如果您的郵件網關和通配符地址已正確配置,則這些通知將通過電子郵件發送,并可直接從您的郵件客戶端回復;自動路由系統將路由答案到正確的線程。
服務器端,有一些輔助函數可幫助您輕松發送消息并管理記錄的關注者:
發布消息
- message_post(self, body='', subject=None, message_type='notification', subtype=None, parent_id=False, attachments=None, **kwargs)?
在現有的線程中發布新消息,返回新的郵件消息 ID。
- message_post_with_view(views_or_xmlid, **kwargs):
使用 view_id 渲染 ir.qweb 引擎來發送郵件/發布消息的輔助方法。這個方法是獨立的,因為在模板和 composer 中沒有任何處理批量視圖的方法。當模板處理 ir ui 視圖時,這個方法可能會消失。
- 參數
record (str or ir.ui.view) – 應發送的視圖的外部ID或記錄
- message_post_with_template(template_id, **kwargs)?
使用模板發送郵件的輔助方法
- 參數
template_id – 用于創建消息正文的模板的ID
**kwargs – 創建一個繼承自 mail.message 的 mail.compose.message 向導的參數
接收消息
當郵件網關處理新郵件時,會調用這些方法。這些郵件可以是新的線程(如果它們通過一個 別名 到達)或者只是現有線程的回復。重寫它們可以讓你根據郵件本身的一些值(例如更新日期或電子郵件地址,將抄送地址添加為關注者等)在線程記錄上設置值。
- message_new(msg_dict, custom_values=None)?
當給定線程模型收到新消息且該消息不屬于現有線程時,由
message_process
調用。默認行為是創建相應模型的新記錄(基于從消息中提取的一些基本信息)??梢酝ㄟ^覆蓋此方法來實現其他行為。
- message_update(msg_dict, update_vals=None)?
當現有線程收到新消息時,由
message_process
調用。默認行為是使用來自傳入電子郵件的update_vals
更新記錄。可以通過覆蓋此方法來實現其他行為。
關注者管理
- message_subscribe(partner_ids=None, channel_ids=None, subtype_ids=None, force=True)?
將合作伙伴添加到記錄的關注者中。
- message_unsubscribe(partner_ids=None, channel_ids=None)?
從記錄的關注者中移除合作伙伴。
記錄更改?
“mail” 模塊為字段添加了強大的跟蹤系統,允許您記錄記錄聊天中特定字段的更改。要將跟蹤添加到字段,請將跟蹤屬性設置為 True。
Example
讓我們跟蹤商務旅行的名稱和負責人的變化:
class BusinessTrip(models.Model):
_name = 'business.trip'
_inherit = ['mail.thread']
_description = 'Business Trip'
name = fields.Char(tracking=True)
partner_id = fields.Many2one('res.partner', 'Responsible',
tracking=True)
guest_ids = fields.Many2many('res.partner', 'Participants')
從現在開始,每次更改行程的名稱或責任人都會在記錄上記錄一個注釋。即使名稱沒有更改,通知中也會顯示“名稱”字段,以提供有關通知的更多上下文。
子類型?
子類型可以更細粒度地控制消息。子類型作為通知的分類系統,允許文檔的訂閱者自定義他們希望接收的通知的子類型。
子類型是作為模塊中的數據創建的;該模型具有以下字段:
name
(必填)-Char
子類型名稱,將顯示在通知自定義彈出窗口中
description
-Char
將添加到此子類型發布的消息中的描述。如果為空,則將添加名稱。
internal
-Boolean
具有內部子類型的消息僅對員工可見,也就是
base.group_user
組的成員可見。parent_id
-Many2one
自動訂閱的鏈接子類型;例如,項目子類型通過此鏈接與任務子類型相關聯。當有人訂閱項目時,他將訂閱此項目下所有使用父子類型找到的任務子類型。
relation_field
-Char
例如,當鏈接項目和任務子類型時,關系字段是任務的 project_id 字段。
res_model
-Char
適用于的模型子類型;如果為 False,則適用于所有模型
default
-Boolean
訂閱時是否默認激活子類型
sequence
-Integer
用于在通知自定義彈出窗口中排序子類型
hidden
-Boolean
通知自定義彈出窗口中是否隱藏子類型
將子類型與字段跟蹤接口相結合,可以訂閱不同類型的通知,具體取決于用戶可能感興趣的內容。為此,您可以覆蓋 _track_subtype()
函數:
- _track_subtype(init_values)?
根據已更新的值,給出由記錄更改觸發的子類型。
- 參數
init_values (dict) – 記錄的原始值;字典中僅包含修改過的字段
- 返回
一個子類型的完整外部 ID,如果沒有觸發子類型,則為 False
Example
讓我們在示例類上添加一個“state”字段,并在該字段更改值時觸發具有特定子類型的通知。
首先,讓我們定義我們的子類型:
<record id="mt_state_change" model="mail.message.subtype">
<field name="name">Trip confirmed</field>
<field name="res_model">business.trip</field>
<field name="default" eval="True"/>
<field name="description">Business Trip confirmed!</field>
</record>
然后,我們需要重寫 track_subtype()
函數。該函數由跟蹤系統調用,以了解應根據當前應用的更改使用哪個子類型。在我們的情況下,當 state
字段從 draft 更改為 confirmed 時,我們希望使用我們閃亮的新子類型:
class BusinessTrip(models.Model):
_name = 'business.trip'
_inherit = ['mail.thread']
_description = 'Business Trip'
name = fields.Char(tracking=True)
partner_id = fields.Many2one('res.partner', 'Responsible',
tracking=True)
guest_ids = fields.Many2many('res.partner', 'Participants')
state = fields.Selection([('draft', 'New'), ('confirmed', 'Confirmed')],
tracking=True)
def _track_subtype(self, init_values):
# init_values contains the modified fields' values before the changes
#
# the applied values can be accessed on the record as they are already
# in cache
self.ensure_one()
if 'state' in init_values and self.state == 'confirmed':
return self.env.ref('my_module.mt_state_change')
return super(BusinessTrip, self)._track_subtype(init_values)
自定義通知?
當向關注者發送通知時,在模板中添加按鈕以允許直接從電子郵件中進行快速操作非常有用。 即使是一個簡單的按鈕直接鏈接到記錄的表單視圖也很有用;但是在大多數情況下,您不希望向門戶用戶顯示這些按鈕。
通知系統可以通過以下方式自定義通知模板:
顯示 訪問按鈕 :這些按鈕在通知電子郵件的頂部可見,允許收件人直接訪問記錄的表單視圖
顯示 關注按鈕 :這些按鈕允許收件人直接從記錄中快速訂閱
顯示 取消關注按鈕 :這些按鈕允許收件人直接快速取消對記錄的訂閱
顯示 自定義操作按鈕 :這些按鈕是對特定路由的調用,允許您直接從電子郵件中執行一些有用的操作(例如將潛在客戶轉換為機會,為費用經理驗證費用報銷單等)。
這些按鈕設置可以應用于不同的組,您可以通過覆蓋函數 _notify_get_groups
來自定義這些組。
- _notify_get_groups(message, groups)?
根據已更新的值,給出由記錄更改觸發的子類型。
- 參數
message (record) – 正在發送的
mail.message
記錄groups (list(tuple)) – 列表,元素為元組(group_name, group_func, group_data),其中: group_name是一個標識符,僅用于覆蓋和操作組。默認組為“user”(與員工用戶相關的收件人)、“portal”(與門戶用戶相關的收件人)和“customer”(未與任何用戶相關的收件人)。覆蓋使用示例是添加一個與res.groups相關聯的組,例如Hr Officers,以為它們設置特定的操作按鈕。group_func是一個函數指針,以合作伙伴記錄為參數。此方法將應用于收件人,以了解他們是否屬于給定的組。僅保留第一個匹配組。評估順序是列表順序。group_data是一個包含通知電子郵件參數的字典,具有以下可能的鍵值對: - has_button_access:是否在電子郵件中顯示Access <Document>。對于新組,默認為True,對于門戶/客戶端,默認為False。 - button_access:按鈕的url和標題的字典 - has_button_follow:是否在電子郵件中顯示Follow(如果收件人當前沒有關注該線程)。對于新組,默認為True,對于門戶/客戶端,默認為False。 - button_follow:按鈕的url和標題的字典 - has_button_unfollow:是否在電子郵件中顯示Unfollow(如果收件人當前正在關注該線程)。對于新組,默認為True,對于門戶/客戶端,默認為False。 - button_unfollow:按鈕的url和標題的字典 - actions:在通知電子郵件中顯示的操作按鈕列表。每個操作都是一個包含按鈕的url和標題的字典。
- 返回
一個子類型的完整外部 ID,如果沒有觸發子類型,則為 False
操作列表中的URL可以通過調用 _notify_get_action_link()
函數自動生成:
- _notify_get_action_link(self, link_type, **kwargs)?
生成當前記錄(或如果設置了kwargs“model”和“res_id”,則在特定記錄上)的給定類型的鏈接。
Example
讓我們向出差狀態更改通知添加自定義按鈕;此按鈕將把狀態重置為草稿,并且僅對(虛構的)Travel Manager組( business.group_trip_manager
)的成員可見。
class BusinessTrip(models.Model):
_name = 'business.trip'
_inherit = ['mail.thread', 'mail.alias.mixin']
_description = 'Business Trip'
# Pevious code goes here
def action_cancel(self):
self.write({'state': 'draft'})
def _notify_get_groups(self, message, groups):
""" Handle Trip Manager recipients that can cancel the trip at the last
minute and kill all the fun. """
groups = super(BusinessTrip, self)._notify_get_groups(message, groups)
self.ensure_one()
if self.state == 'confirmed':
app_action = self._notify_get_action_link('method',
method='action_cancel')
trip_actions = [{'url': app_action, 'title': _('Cancel')}]
new_group = (
'group_trip_manager',
lambda partner: bool(partner.user_ids) and
any(user.has_group('business.group_trip_manager')
for user in partner.user_ids),
{
'actions': trip_actions,
})
return [new_group] + groups
請注意,我可以在此方法之外定義我的評估函數,并定義全局函數來代替lambda,但為了在這些有時會很無聊的文檔文件中更加簡潔和不冗長,我選擇前者而不是后者。
覆蓋默認值?
您可以通過多種方式自定義 mail.thread
模型的行為,包括但不限于以下方式:
_mail_post_access
-Model
屬性需要發布模型消息的必要訪問權限;默認情況下需要
write
訪問權限,也可以設置為read
- 上下文鍵:
這些上下文鍵可用于在調用
create()
或write()
(或任何其他可能有用的方法)期間,有些控制mail.thread
功能,如自動訂閱或字段跟蹤。mail_create_nosubscribe
: 在創建或發送消息時,不訂閱當前用戶到記錄線程mail_create_nolog
: 在創建時,不記錄自動的’<Document>已創建’消息mail_notrack
: 在創建和寫入時,不執行值跟蹤創建消息tracking_disable
: 在創建和寫入時,不執行MailThread功能(自動訂閱,跟蹤,發布等)mail_auto_delete
: 自動刪除郵件通知;默認為Truemail_notify_force_send
: 如果要發送的電子郵件通知少于50個,則直接發送而不使用隊列;默認為Truemail_notify_user_signature
: 在電子郵件通知中添加當前用戶簽名;默認為True
郵件別名?
別名是可配置的電子郵件地址,它們與特定記錄鏈接(通常繼承“mail.alias.mixin”模型),當通過電子郵件聯系時將創建新記錄。它們是使您的系統從外部可訪問的簡單方法,允許用戶或客戶快速在您的數據庫中創建記錄,而無需直接連接到Odoo。
別名 vs. 郵件入口網關?
有些人使用傳入郵件網關來實現同樣的目的。但是,您仍然需要一個正確配置的郵件網關來使用別名,但是一個單獨的萬能域名就足夠了,因為所有路由都將在Odoo內部完成。別名比郵件網關具有幾個優點:
- 更容易配置
一個入站網關可以被多個別名使用;這樣可以避免在您的域名上配置多個電子郵件(所有配置都在Odoo內部完成)。
配置別名無需系統訪問權限
- 更連貫
可在相關記錄上配置,而不是在設置子菜單中
- 更容易在服務器端進行覆蓋
Mixin模型從一開始就被構建為可擴展的,使您可以比郵件網關更輕松地從傳入的電子郵件中提取有用的數據。
別名支持集成?
通常情況下,別名是在父模型上配置的,當通過電子郵件聯系時,將創建特定的記錄。例如,項目具有用于創建任務或問題的別名,銷售團隊具有用于生成潛在客戶的別名。
注解
別名創建的模型 必須 繼承 mail_thread
模型。
通過繼承 mail.alias.mixin
來添加別名支持;這個 mixin 將為每個父類記錄生成一個新的 mail.alias
記錄(例如,每個 project.project
記錄在創建時都會初始化其 mail.alias
記錄)。
注解
別名也可以手動創建,并由一個簡單的 Many2one
字段支持。本指南假定您希望更完整地集成,自動創建別名,記錄特定的默認值等。
與 mail.thread
繼承不同, mail.alias.mixin
需要 一些特定的重寫才能正常工作。這些重寫將指定創建的別名的值,例如它必須創建的記錄類型,以及根據父對象可能具有的一些默認值。
- _get_alias_model_name(vals)?
返回別名的模型名稱。未回復現有記錄的傳入電子郵件將導致創建此別名模型的新記錄。該值可能取決于“vals”,即在創建此模型的記錄時傳遞給“create”的值字典。
- 參數
dict (vals) – 新創建的記錄將持有別名的值
- 返回
模型名稱
- 返回類型
- _get_alias_values()?
返回值用于創建別名,或在創建后對別名進行寫入。雖然不是完全必需的,但通常需要通過在別名的“alias_defaults”字段中設置默認值字典來確保新創建的記錄將鏈接到別名的父級(即在正確的項目中創建任務)。
- 返回
將寫入新別名的值的字典
- 返回類型
_get_alias_values()
覆蓋方法非常有趣,因為它可以輕松修改別名的行為??梢栽趧e名上設置以下字段,這些字段特別有趣:
alias_name
-Char
電子郵件別名的名稱,例如,如果您想捕獲 <jobs@example.odoo.com> 的電子郵件,則為“jobs”
alias_user_id
-Many2one
(res.users
)在收到此別名的電子郵件時創建記錄的所有者;如果未設置此字段,則系統將嘗試根據發件人(From)地址找到正確的所有者,如果找不到該地址的系統用戶,則將使用管理員帳戶。
alias_defaults
-Text
Python 字典,用于在為此別名創建新記錄時提供默認值
alias_force_thread_id
-Integer
可選的線程(記錄)ID,所有傳入的消息都將附加到其中,即使它們沒有回復它;如果設置,這將完全禁用新記錄的創建
alias_contact
-Selection
使用郵件網關在文檔上發布消息的策略
所有人 : 所有人都可以發布
合作伙伴 :僅限已認證的合作伙伴
followers : 僅限于相關文檔的關注者或者關注頻道的成員
請注意,別名使用 委托繼承 ,這意味著雖然別名存儲在另一個表中,但您可以直接從父對象訪問所有這些字段。這使得您可以輕松地從記錄的表單視圖中配置別名。
Example
讓我們在出差類上添加別名,通過電子郵件即可即時創建費用。
class BusinessTrip(models.Model):
_name = 'business.trip'
_inherit = ['mail.thread', 'mail.alias.mixin']
_description = 'Business Trip'
name = fields.Char(tracking=True)
partner_id = fields.Many2one('res.partner', 'Responsible',
tracking=True)
guest_ids = fields.Many2many('res.partner', 'Participants')
state = fields.Selection([('draft', 'New'), ('confirmed', 'Confirmed')],
tracking=True)
expense_ids = fields.One2many('business.expense', 'trip_id', 'Expenses')
alias_id = fields.Many2one('mail.alias', string='Alias', ondelete="restrict",
required=True)
def _get_alias_model_name(self, vals):
""" Specify the model that will get created when the alias receives a message """
return 'business.expense'
def _get_alias_values(self):
""" Specify some default values that will be set in the alias at its creation """
values = super(BusinessTrip, self)._get_alias_values()
# alias_defaults holds a dictionary that will be written
# to all records created by this alias
#
# in this case, we want all expense records sent to a trip alias
# to be linked to the corresponding business trip
values['alias_defaults'] = {'trip_id': self.id}
# we only want followers of the trip to be able to post expenses
# by default
values['alias_contact'] = 'followers'
return values
class BusinessExpense(models.Model):
_name = 'business.expense'
_inherit = ['mail.thread']
_description = 'Business Expense'
name = fields.Char()
amount = fields.Float('Amount')
trip_id = fields.Many2one('business.trip', 'Business Trip')
partner_id = fields.Many2one('res.partner', 'Created by')
我們希望在出差表單視圖中輕松配置我們的別名,因此讓我們將以下內容添加到我們的表單視圖中:
<page string="Emails">
<group name="group_alias">
<label for="alias_name" string="Email Alias"/>
<div name="alias_def">
<!-- display a link while in view mode and a configurable field
while in edit mode -->
<field name="alias_id" class="oe_read_only oe_inline"
string="Email Alias" required="0"/>
<div class="oe_edit_only oe_inline" name="edit_alias"
style="display: inline;" >
<field name="alias_name" class="oe_inline"/>
@
<field name="alias_domain" class="oe_inline" readonly="1"/>
</div>
</div>
<field name="alias_contact" class="oe_inline"
string="Accept Emails From"/>
</group>
</page>
現在我們可以直接從表單視圖更改別名地址,并更改可以向別名發送電子郵件的人。
我們可以在我們的費用模型上重寫 message_new()
方法,以便在創建費用時從我們的電子郵件中獲取值:
class BusinessExpense(models.Model):
# Previous code goes here
# ...
def message_new(self, msg, custom_values=None):
""" Override to set values according to the email.
In this simple example, we simply use the email title as the name
of the expense, try to find a partner with this email address and
do a regex match to find the amount of the expense."""
name = msg_dict.get('subject', 'New Expense')
# Match the last occurrence of a float in the string
# Example: '50.3 bar 34.5' becomes '34.5'. This is potentially the price
# to encode on the expense. If not, take 1.0 instead
amount_pattern = '(\d+(\.\d*)?|\.\d+)'
expense_price = re.findall(amount_pattern, name)
price = expense_price and float(expense_price[-1][0]) or 1.0
# find the partner by looking for it's email
partner = self.env['res.partner'].search([('email', 'ilike', email_address)],
limit=1)
defaults = {
'name': name,
'amount': price,
'partner_id': partner.id
}
defaults.update(custom_values or {})
res = super(BusinessExpense, self).message_new(msg, custom_values=defaults)
return res
活動跟蹤?
活動是用戶在文檔上必須執行的操作,例如打電話或組織會議?;顒与S郵件模塊一起提供,因為它們集成在 Chatter 中,但 不與 mail.thread 捆綁 ?;顒邮?mail.activity
類的記錄,具有類型( mail.activity.type
)、名稱、描述、計劃時間(等等)。待處理的活動在聊天窗口小部件中的消息歷史記錄上方可見。
您可以在您的對象上使用 mail.activity.mixin
類來集成活動,并使用特定的小部件(通過字段 activity_ids
)在記錄的表單視圖和看板視圖中顯示它們(分別使用 mail_activity
和 kanban_activity
小部件)。
Example
組織商務旅行是一個繁瑣的過程,跟蹤需要的活動,如訂購飛機票或機場出租車可能會很有用。為此,我們將在我們的模型上添加活動mixin,并在我們的旅行消息歷史記錄中顯示下一個計劃的活動。
class BusinessTrip(models.Model):
_name = 'business.trip'
_inherit = ['mail.thread', 'mail.activity.mixin']
_description = 'Business Trip'
name = fields.Char()
# [...]
我們修改旅行的表單視圖以顯示它們的下一個活動:
<record id="businness_trip_form" model="ir.ui.view">
<field name="name">business.trip.form</field>
<field name="model">business.trip</field>
<field name="arch" type="xml">
<form string="Business Trip">
<!-- Your usual form view goes here -->
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="activity_ids" widget="mail_activity"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
您可以在以下模型中找到具體的集成示例:
crm.lead
在CRM( crm )應用程序中銷售( sale )應用程序中的
sale.order
project.task
在項目( project )應用程序中
網站功能?
訪客追蹤?
utm.mixin
類可以通過鏈接到指定資源的參數來跟蹤在線營銷/通信活動。該 mixin 將向您的模型添加 3 個字段:
campaign_id
:Many2one
字段,指向utm.campaign
對象(例如 Christmas_Special、Fall_Collection 等)source_id
:Many2one
字段,指向utm.source
對象(例如搜索引擎、郵件列表等)medium_id
:Many2one
字段,指向utm.medium
對象(例如: 郵件、電子郵件、社交網絡更新等)
這些模型只有一個字段 name
(即它們只是用來區分活動,但沒有任何特定的行為)。
一旦客戶使用這些參數訪問您的網站(即 https://www.odoo.com/?campaign_id=mixin_talk&source_id=www.odoo.com&medium_id=website),這些參數將在訪問者的網站上設置三個cookie。一旦從網站(即潛在客戶表單、職位申請等)創建了繼承utm.mixin的對象,utm.mixin代碼將啟動并從cookie中獲取值以將其設置在新記錄中。完成后,您可以像定義報告和視圖(按組等)時使用其他字段一樣使用campaign/source/medium字段。
要擴展此行為,只需將關系字段添加到簡單模型中(該模型應支持“快速創建”(即使用單個“name”值調用 create()
)并擴展函數 tracking_fields()
class UtmMyTrack(models.Model):
_name = 'my_module.my_track'
_description = 'My Tracking Object'
name = fields.Char(string='Name', required=True)
class MyModel(models.Models):
_name = 'my_module.my_model'
_inherit = ['utm.mixin']
_description = 'My Tracked Object'
my_field = fields.Many2one('my_module.my_track', 'My Field')
@api.model
def tracking_fields(self):
result = super(MyModel, self).tracking_fields()
result.append([
# ("URL_PARAMETER", "FIELD_NAME_MIXIN", "NAME_IN_COOKIES")
('my_field', 'my_field', 'odoo_utm_my_field')
])
return result
這將告訴系統創建一個名為 odoo_utm_my_field 的cookie,其中包含在url參數 my_field
中找到的值;一旦通過網站表單的調用創建了此模型的新記錄, utm.mixin
的通用 create()
方法將從cookie中獲取此字段的默認值(如果尚不存在,則將動態創建 my_module.my_track
記錄)。
您可以在以下模型中找到具體的集成示例:
crm.lead
在CRM( crm )應用程序中hr.applicant
在招聘流程( hr_recruitment )應用程序中helpdesk.ticket
在 Helpdesk 應用程序中 ( helpdesk - 僅限 Odoo 企業版)
網站可見性?
您可以很容易地在任何記錄上添加網站可見性切換。雖然這個 mixin 手動實現起來很容易,但它是繼 mail.thread
繼承之后最常用的 mixin;這證明了它的實用性。這個 mixin 的典型用例是任何具有前端頁面的對象;能夠控制頁面的可見性允許您在編輯頁面時花費時間,并在滿意時才發布它。
如果要包含此功能,您只需要繼承 website.published.mixin
:
class BlogPost(models.Model):
_name = "blog.post"
_description = "Blog Post"
_inherit = ['website.published.mixin']
此 mixin 在您的模型上添加了 2 個字段:
注意,最后一個字段是計算字段,必須為您的類實現:
def _compute_website_url(self):
for blog_post in self:
blog_post.website_url = "/blog/%s" % (log_post.blog_id)
一旦機制到位,您只需調整前端和后端視圖即可使其可訪問。在后端,通常是在按鈕框中添加一個按鈕:
<button class="oe_stat_button" name="website_publish_button"
type="object" icon="fa-globe">
<field name="website_published" widget="website_button"/>
</button>
在前端,需要進行一些安全檢查,以避免向網站訪問者顯示“編輯”按鈕:
<div id="website_published_button" class="float-right"
groups="base.group_website_publisher"> <!-- or any other meaningful group -->
<t t-call="website.publish_management">
<t t-set="object" t-value="blog_post"/>
<t t-set="publish_edit" t-value="True"/>
<t t-set="action" t-value="'blog.blog_post_action'"/>
</t>
</div>
請注意,您必須將您的對象作為變量 object
傳遞給模板;在此示例中, blog.post
記錄被傳遞為 blog_post
變量到 qweb
渲染引擎,因此在發布管理模板中必須指定。 publish_edit
變量允許前端按鈕鏈接到后端(允許您輕松地在前端和后端之間切換);如果設置了該變量,則必須在 action
變量中指定要在后端調用的完整外部 ID(請注意,模型必須存在一個表單視圖)。
在Mixin中定義了 website_publish_button
操作,并根據您的對象調整其行為:如果類具有有效的 website_url
計算函數,則用戶單擊按鈕時將被重定向到前端;然后用戶可以直接從前端發布頁面。這確保不會發生意外的在線發布。如果沒有計算函數,則簡單地觸發布爾值 website_published
。
網站元數據?
這個簡單的mixin允許您輕松地在前端頁面中注入元數據。
class BlogPost(models.Model):
_name = "blog.post"
_description = "Blog Post"
_inherit = ['website.seo.metadata', 'website.published.mixin']
此 mixin 在您的模型上添加了 3 個字段:
website_meta_title
:Char
字段,允許您為頁面設置額外的標題website_meta_description
:Char
字段,包含頁面的簡短描述(有時用于搜索引擎結果)website_meta_keywords
:Char
字段,包含一些關鍵詞,幫助您的頁面被搜索引擎更精確地分類;”Promote” 工具將幫助您輕松選擇詞匯相關的關鍵詞
這些字段可以使用編輯器工具欄中的“Promote”工具在前端進行編輯。設置這些字段可以幫助搜索引擎更好地索引您的頁面。請注意,搜索引擎不僅僅基于這些元數據來生成結果;最佳的SEO實踐仍然是獲得可靠來源的引用。
其他?
客戶評分?
評分 mixin 允許發送電子郵件請求客戶評分,在看板流程中自動轉換并聚合您的評分統計信息。
在您的模型上添加評分?
要添加評分支持,只需繼承 rating.mixin
模型:
class MyModel(models.Models):
_name = 'my_module.my_model'
_inherit = ['rating.mixin', 'mail.thread']
user_id = fields.Many2one('res.users', 'Responsible')
partner_id = fields.Many2one('res.partner', 'Customer')
Mixin的行為會根據您的模型進行調整:
如果您的模型中存在
partner_id
字段,則rating.rating
記錄將鏈接到該字段。如果您使用的字段不是
partner_id
,則可以使用函數rating_get_partner_id()
覆蓋此行為。
The
rating.rating
記錄將鏈接到您模型的user_id
字段的合作伙伴(如果該字段存在)(即被評價的合作伙伴)如果您使用的字段不是
user_id
,則可以使用函數rating_get_rated_partner_id()
覆蓋此行為(請注意,該函數必須返回一個res.partner
對象,對于user_id
,系統會自動獲取用戶的合作伙伴)
如果您的模型繼承自
mail.thread
,聊天記錄將顯示評分事件。
通過電子郵件發送評分請求?
如果您希望發送電子郵件請求評分,只需生成一封電子郵件,其中包含指向評分對象的鏈接。一個非?;镜碾娮余]件模板可能如下所示:
<record id="rating_my_model_email_template" model="mail.template">
<field name="name">My Model: Rating Request</field>
<field name="email_from">${object.rating_get_rated_partner_id().email or '' | safe}</field>
<field name="subject">Service Rating Request</field>
<field name="model_id" ref="my_module.model_my_model"/>
<field name="partner_to" >${object.rating_get_partner_id().id}</field>
<field name="auto_delete" eval="True"/>
<field name="body_html"><![CDATA[
% set access_token = object.rating_get_access_token()
<p>Hi,</p>
<p>How satsified are you?</p>
<ul>
<li><a href="/rate/${access_token}/5">Satisfied</a></li>
<li><a href="/rate/${access_token}/3">Okay</a></li>
<li><a href="/rate/${access_token}/1">Dissatisfied</a></li>
</ul>
]]></field>
</record>
然后您的客戶將收到一封電子郵件,其中包含指向一個簡單網頁的鏈接,允許他們提供有關與您的用戶的交互的反饋(包括自由文本反饋消息)。
您可以通過為評分定義一個操作,輕松地將評分與表單視圖集成起來:
<record id="rating_rating_action_my_model" model="ir.actions.act_window">
<field name="name">Customer Ratings</field>
<field name="res_model">rating.rating</field>
<field name="view_mode">kanban,pivot,graph</field>
<field name="domain">[('res_model', '=', 'my_module.my_model'), ('res_id', '=', active_id), ('consumed', '=', True)]</field>
</record>
<record id="my_module_my_model_view_form_inherit_rating" model="ir.ui.view">
<field name="name">my_module.my_model.view.form.inherit.rating</field>
<field name="model">my_module.my_model</field>
<field name="inherit_id" ref="my_module.my_model_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='button_box']" position="inside">
<button name="%(rating_rating_action_my_model)d" type="action"
class="oe_stat_button" icon="fa-smile-o">
<field name="rating_count" string="Rating" widget="statinfo"/>
</button>
</xpath>
</field>
</record>
請注意,評級有默認視圖(看板、透視圖、圖表),可以快速查看客戶評級的總體情況。
您可以在以下模型中找到具體的集成示例:
project.task
在項目( rating_project )應用程序中helpdesk.ticket
在 Helpdesk 應用程序中 ( helpdesk - 僅限 Odoo 企業版)