運用 Odoo 知識將必要的部分拆解出來,再搭配 GenAI 來新增功能,這次實作去年的 Day11 的功能,詳細的內容可以參考下面連結。
[Day11] 圖書館管理系統 ISBN 驗證跟預設搜尋選項
"""
# books.py
from odoo import models, fields
class Books(models.Model):
_name = 'library.books'
_description = 'Library Books'
name = fields.Char(string='Book Name', required=True)
isbn = fields.Char(string='ISBN')
book_type = fields.Selection([
('paper', 'Paper'),
('ebook', 'E-Book'),
('other', 'Other')],
string='Book Type', default='paper')
description = fields.Text(string='Description')
stock = fields.Integer(string='Stock')
price_twd = fields.Float(string='Price (TWD)')
average_rating = fields.Float(string='Average Rating', digits=(2, 2))
publish_date = fields.Date(string='Publish Date')
last_rent_date = fields.Datetime(string='Last Rent Date')
rentable = fields.Boolean(string='Rentable', default=True)
cover_image = fields.Binary(string='Cover Image')
"""
"""
book_views.xml
<odoo>
<record id="view_book_form" model="ir.ui.view">
<field name="name">library.books.form</field>
<field name="model">library.books</field>
<field name="arch" type="xml">
<form string="Book">
<sheet>
<group>
<field name="name"/>
<field name="isbn"/>
<field name="book_type"/>
<field name="description"/>
<field name="stock"/>
<field name="price_twd"/>
<field name="average_rating"/>
<field name="publish_date"/>
<field name="last_rent_date"/>
<field name="rentable"/>
<field name="cover_image" widget="image"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="view_book_tree" model="ir.ui.view">
<field name="name">library.books.tree</field>
<field name="model">library.books</field>
<field name="arch" type="xml">
<tree string="Books">
<field name="name"/>
<field name="isbn"/>
<field name="book_type"/>
<field name="stock"/>
<field name="price_twd"/>
<field name="average_rating"/>
<field name="publish_date"/>
<field name="last_rent_date"/>
<field name="rentable"/>
</tree>
</field>
</record>
</odoo>
"""
上面是使用 Odoo 17 客製化模組的 Model 和 View,我要新增一個功能 Check ISBN validation (檢查 ISBN 是否合理),並且是在新增 books 的 Form View 裡面,用 Button (按鈕) 來觸發,請用繁體中文
你可以在 Odoo 17 模組中新增一個檢查 ISBN 是否合理的功能,並在 Form View 中透過按鈕來觸發這個檢查。以下是具體的步驟和範例程式碼:
修改 Model (books.py):新增一個方法來檢查 ISBN,並透過按鈕來觸發該方法。
更新 View (book_views.xml):在 Form View 中新增一個按鈕來執行 ISBN 檢查。
首先,我們在 Books 模型中新增一個 check_isbn 方法,這個方法會檢查 ISBN 是否有效。
from odoo import models, fields, api
from odoo.exceptions import ValidationError
class Books(models.Model):
_name = 'library.books'
_description = 'Library Books'
name = fields.Char(string='Book Name', required=True)
isbn = fields.Char(string='ISBN')
book_type = fields.Selection([
('paper', 'Paper'),
('ebook', 'E-Book'),
('other', 'Other')],
string='Book Type', default='paper')
description = fields.Text(string='Description')
stock = fields.Integer(string='Stock')
price_twd = fields.Float(string='Price (TWD)')
average_rating = fields.Float(string='Average Rating', digits=(2, 2))
publish_date = fields.Date(string='Publish Date')
last_rent_date = fields.Datetime(string='Last Rent Date')
rentable = fields.Boolean(string='Rentable', default=True)
cover_image = fields.Binary(string='Cover Image')
@api.model
def is_valid_isbn(self, isbn):
"""簡單的 ISBN 驗證方法,支援 ISBN-10 和 ISBN-13"""
isbn = isbn.replace('-', '').replace(' ', '')
if len(isbn) == 10:
total = sum((10 - i) * int(x) for i, x in enumerate(isbn[:9])) + (10 if isbn[-1] == 'X' else int(isbn[-1]))
return total % 11 == 0
elif len(isbn) == 13:
total = sum(int(x) * (3 if i % 2 else 1) for i, x in enumerate(isbn))
return total % 10 == 0
return False
def check_isbn(self):
"""檢查 ISBN,並在無效時拋出錯誤"""
if not self.isbn:
raise ValidationError("ISBN 欄位不能為空。")
if not self.is_valid_isbn(self.isbn):
raise ValidationError("輸入的 ISBN 無效,請檢查後再試。")
return True
在這裡,我們新增了 is_valid_isbn 方法來進行 ISBN 驗證。此方法會檢查 ISBN 是符合 ISBN-10 或 ISBN-13 規範。如果驗證失敗,check_isbn 會丟出 ValidationError。
接下來,我們在 Form View 裡新增一個按鈕來觸發 ISBN 檢查。
<odoo>
<record id="view_book_form" model="ir.ui.view">
<field name="name">library.books.form</field>
<field name="model">library.books</field>
<field name="arch" type="xml">
<form string="Book">
<sheet>
<group>
<field name="name"/>
<field name="isbn"/>
<field name="book_type"/>
<field name="description"/>
<field name="stock"/>
<field name="price_twd"/>
<field name="average_rating"/>
<field name="publish_date"/>
<field name="last_rent_date"/>
<field name="rentable"/>
<field name="cover_image" widget="image"/>
</group>
<footer>
<button name="check_isbn" string="檢查 ISBN" type="object" class="btn-primary"/>
</footer>
</sheet>
</form>
</field>
</record>
</odoo>
當你在書本的 Form View 中點擊「檢查 ISBN」按鈕時,系統會自動驗證輸入的 ISBN 是否有效,並在無效時顯示錯誤訊息。
這樣的設計能幫助用戶確保輸入的 ISBN 是有效的,也提升了資料的準確性。
請再新增 View 裡新增 search view
在 Odoo 中,你可以透過 search view 來讓使用者搜尋特定欄位的資料。你可以在 book_views.xml 中新增一個 search view,讓使用者能夠根據書本名稱、ISBN 或其他欄位進行搜尋。
下面是如何修改 book_views.xml,以新增 search view:
<odoo>
<record id="view_book_form" model="ir.ui.view">
<field name="name">library.books.form</field>
<field name="model">library.books</field>
<field name="arch" type="xml">
<form string="Book">
<sheet>
<group>
<field name="name"/>
<field name="isbn"/>
<field name="book_type"/>
<field name="description"/>
<field name="stock"/>
<field name="price_twd"/>
<field name="average_rating"/>
<field name="publish_date"/>
<field name="last_rent_date"/>
<field name="rentable"/>
<field name="cover_image" widget="image"/>
</group>
<footer>
<button name="check_isbn" string="檢查 ISBN" type="object" class="btn-primary"/>
</footer>
</sheet>
</form>
</field>
</record>
<record id="view_book_tree" model="ir.ui.view">
<field name="name">library.books.tree</field>
<field name="model">library.books</field>
<field name="arch" type="xml">
<tree string="Books">
<field name="name"/>
<field name="isbn"/>
<field name="book_type"/>
<field name="stock"/>
<field name="price_twd"/>
<field name="average_rating"/>
<field name="publish_date"/>
<field name="last_rent_date"/>
<field name="rentable"/>
</tree>
</field>
</record>
<!-- 新增 search view -->
<record id="view_book_search" model="ir.ui.view">
<field name="name">library.books.search</field>
<field name="model">library.books</field>
<field name="arch" type="xml">
<search string="Search Books">
<field name="name" string="Book Name"/>
<field name="isbn" string="ISBN"/>
<field name="book_type" string="Book Type"/>
<field name="stock" string="Stock"/>
<filter name="filter_rentable" string="Rentable" domain="[('rentable', '=', True)]"/>
<filter name="filter_not_rentable" string="Not Rentable" domain="[('rentable', '=', False)]"/>
<group expand="0" string="Group By">
<filter string="Book Type" group_by="book_type"/>
<filter string="Rentable" group_by="rentable"/>
</group>
</search>
</field>
</record>
</odoo>
當你進入書本的 tree view 或 list view 時,會看到上方的搜尋欄位,使用者可以依照書本名稱、ISBN 進行篩選,也可以透過過濾器篩選出可租借或不可租借的書籍,並且可以根據書本類型或租借狀態來群組顯示。
這樣可以大幅提升使用者的搜尋和篩選體驗,方便快速找到所需的書籍資料。