約束(Constraints)
上一章介紹了向模型中添加一些業務邏輯的能力,我們現在可以將按鈕鏈接到業務代碼,但如何防止用戶輸入錯誤的資料?例如,在我們的房地產模塊中,沒有什么可以阻止用戶設定負預期價格,
odoo提供了兩種設定自動驗證恒定式的方法:Python約束 and SQL約束,
SQL
參考:與此主題相關的檔案可以查看 Models 和PostgreSQL檔案
我們通過模型屬性_sql_constraints來定義SQL約束,該屬性被賦值為一個包含三元組(name, sql_definition, message)的串列,其中name為一個合法的SQL約束名稱, sql_definition 為表約束運算式,message為錯誤訊息,
一個簡單的示例,
class AccountAnalyticDistribution(models.Model):
_name = 'account.analytic.distribution'
_description = 'Analytic Account Distribution'
_rec_name = 'account_id'
account_id = fields.Many2one('account.analytic.account', string='Analytic Account', required=True)
percentage = fields.Float(string='Percentage', required=True, default=100.0)
name = fields.Char(string='Name', related='account_id.name', readonly=False)
tag_id = fields.Many2one('account.analytic.tag', string="Parent tag", required=True)
_sql_constraints = [
('check_percentage', 'CHECK(percentage >= 0 AND percentage <= 100)',
'The percentage of an analytic distribution should be between 0 and 100.')
]
一個簡單的示例--唯一約束
class BlogTagCategory(models.Model):
_name = 'blog.tag.category'
_description = 'Blog Tag Category'
_order = 'name'
name = fields.Char('Name', required=True, translate=True)
tag_ids = fields.One2many('blog.tag', 'category_id', string='Tags')
_sql_constraints = [
('name_uniq', 'unique (name)', "Tag category already exists !"),
]
練習--添加SQL約束
添加以下約束到對應模型:
- 房產預期價格必須為正數
- 房產售價必須為正數
- 報價必須為正數
- 房產標簽名稱和型別名稱必須唯一
使用-u estate選項重新啟動服務器以查看結果,請注意,可能存在阻止設定SQL約束的資料,可能會彈出類似以下內容的錯誤訊息:
ERROR rd-demo odoo.schema: Table 'estate_property_offer': unable to add constraint 'estate_property_offer_check_price' as CHECK(price > 0)
例如,如果某些報價的價格為零,則無法應用約束,可以洗掉、修正有問題的資料以應用新的約束,
修改odoo14\custom\estate\models\estate_property.py,添加SQL約束
_sql_constraints = [
('check_expected_price', 'CHECK(expected_price > 0)', 'expected price should be positive.'),
('check_selling_price', 'CHECK(selling_price > 0)', 'selling price should be positive.')
]
注意:當selling_price為null時,也通過CHECK(selling_price > 0)校驗的
修改odoo14\custom\estate\models\estate_property_tag.py,添加SQL約束
_sql_constraints = [('check_tag', 'unique(name)', 'Tag name must be unique !')]
修改odoo14\custom\estate\models\estate_property_type.py,添加SQL約束
_sql_constraints = [('check_name', 'unique(name)', 'Type name must be unique !')]
重啟服務驗證
預期效果影片:https://www.odoo.com/documentation/14.0/zh_CN/_images/sql_01.gif

https://www.odoo.com/documentation/14.0/zh_CN/_images/sql_02.gif

Python
參考: 主題關聯檔案可查看constrains().
SQL約束是確保資料一致性的有效方法,然而,可能需要進行更復雜的檢查,這需要Python代碼,在這種情況下,我們需要一個Python約束,
Python約束定義為用 constrains()修飾的方法,并在記錄集上呼叫,修飾符指定約束中涉及哪些欄位,當修改這些欄位中的任何欄位時,將自動計算約束,如果不滿足該方法的恒定式,則該方法將引發例外:
from odoo.exceptions import ValidationError
...
@api.constrains('date_end')
def _check_date_end(self):
for record in self:
if record.date_end < fields.Date.today():
raise ValidationError("The end date cannot be set in the past")
# all records passed the test, don't return anything
一個簡單的示例,
@api.constrains('quantity')
def check_quantity(self):
for quant in self:
if quant.location_id.usage != 'inventory' and quant.lot_id and quant.product_id.tracking == 'serial' \
and float_compare(abs(quant.quantity), 1, precision_rounding=quant.product_uom_id.rounding) > 0:
raise ValidationError(_('The serial number has already been assigned: \n Product: %s, Serial Number: %s') % (quant.product_id.display_name, quant.lot_id.name))
練習--添加Python約束
添加售價不能低于預期價格90%的約束
提示: 報價生效前,保持售價為0,你需要對校驗進行微調,以便把這個考慮在內,
警告
當和浮點數打交道時,總是使用從
odoo.tools.float_utils匯入的float_compare()和float_is_zero()方法
確保每次售價或者預期價格改變時,自動觸發約束
修改odoo14\custom\estate\models\estate_property.py
匯入 ValidationError
from odoo.exceptions import ValidationError
最末尾添加以下代碼
@api.constrains('selling_price', 'expected_price')
def _check_selling_price(self):
for record in self:
if record.selling_price < self.expected_price * 0.9:
raise ValidationError("selling price can`t not lower then 90 percent of expected price")
重啟服務,瀏覽器中驗證
預期效果影片:https://www.odoo.com/documentation/14.0/zh_CN/_images/python.gif

SQL約束通常比Python約束更效率,當性能很重要時,總是首選SQL約束而不是Python約束,
作者:授客
微信/QQ:1033553122
全國軟體測驗QQ交流群:7156436
Git地址:https://gitee.com/ishouke
友情提示:限于時間倉促,文中可能存在錯誤,歡迎指正、評論!
作者五行缺錢,如果覺得文章對您有幫助,請掃描下邊的二維碼打賞作者,金額隨意,您的支持將是我繼續創作的源動力,打賞后如有任何疑問,請聯系我!!!
微信打賞
支付寶打賞 全國軟體測驗交流QQ群
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/549400.html
標籤:其他
上一篇:MyBatis常見問題
