GenAI 時代下,處理大型專案需要分而治之 (Odoo 模組即是),處理 Odoo 模組需要 Odoo 知識。
GenAI 非常厲害,但它處理大型專案時的記憶能力有限。因此,學習如何將專案拆解成更小的單位並逐步實作,是成功完成專案的關鍵。
呼應第一天寫的文章,【Day01】GenAI 這麼強大,為什麼還要學程式呢?,以下來看看我的 GenAI 實作。
可以很盡責跟你說,上一個實作有缺陷,首先,列舉幾個點:
__init__.py
並且還有這個 Messenge,也是在述說沒有 Security Group
Rule access_library_books has no group, this is a deprecated feature. Every access-granting rule should specify a group.
我們就這幾個點依序使用 GenAI 克服。
"""
# 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,請幫我補齊 Menu 欠缺的部分
要在 Odoo 17 中補齊 Library 模組的 Menu 定義,可以使用 ir.ui.menu 模型來新增目錄,並把你定義的 library.books 模型與相關視圖綁定到該目錄下。以下是完整的 book_menu.xml 補充部分:
<odoo>
    <!-- Action for Tree and Form views of Books -->
    <record id="action_book_list" model="ir.actions.act_window">
        <field name="name">Books</field>
        <field name="res_model">library.books</field>
        <field name="view_mode">tree,form</field>
        <field name="help" type="html">
            <p class="oe_view_nocontent_create">
                Create your first book record
            </p>
        </field>
    </record>
    <!-- Library main menu -->
    <menuitem id="menu_library_root" name="Library"/>
    <!-- Submenu for Books -->
    <menuitem id="menu_library_books" 
              name="Books" 
              parent="menu_library_root"
              action="action_book_list"/>
</odoo>
解釋:
這樣,當你在 Odoo 17 中安裝這個模組後,應該會在應用程式介面看到 "Library" 主目錄,並且可以進入 "Books" 子目錄來管理書籍資料。
你可以將這段 XML 儲存為 book_menu.xml 並將它加到你的模組 __manifest__.py 文件中的 data 欄位中,如此安裝模組時會一併載入:
'data': [
    'views/book_views.xml',
    'views/book_menu.xml',
],
請新增最簡易的 Security Group 和 Access Rule
以下是如何新增最簡單的 Security Group 和 Access Rule,確保使用者只有在擁有正確的權限時才能查看、創建、修改或刪除 library.books 模型中的記錄。
Security Group & Access Rule 定義:
security/ir.model.access.csv (新增)
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_library_books_user,access.library.books.user,model_library_books,group_library_books_user,1,1,1,1
security/library_security.xml (新增)
<odoo>
    <!-- Security group for library users -->
    <record id="group_library_books_user" model="res.groups">
        <field name="name">Library Books User</field>
        <field name="category_id" ref="base.module_category_hidden"/>
    </record>
</odoo>
解釋:
更新 manifest.py 文件:
確保在你的模組的 manifest.py 文件中,加入這些安全性設定的文件路徑:
'data': [
    'security/library_security.xml',
    'security/ir.model.access.csv',
    'views/book_views.xml',
    'views/book_menu.xml',
],
這樣你就定義了一個最簡易的 Security Group 及其 Access Rule,用來管理 library.books 模型的資料。
__init__.py請給我完整的 Module 結構,只需要檔名讓我檢查是否有缺檔案
library/
│
├── __init__.py
├── __manifest__.py
│
├── models/
│   ├── __init__.py
│   └── books.py
│
├── security/
│   ├── ir.model.access.csv
│   └── library_security.xml
│
├── views/
│   ├── book_views.xml
│   └── book_menu.xml
│
└── data/
    └── (可以用來放預設資料,如有需要)
各檔案功能:
__init__.py: 用於初始化模組,在 models/ 資料夾中的 books.py 文件需被匯入。__manifest__.py: 包含模組的說明、依賴性、數據路徑等模組的基本定義。GenAI 在 Odoo 模組開發中的困境
使用 GenAI 的策略