Thêm button cho form view trong Odoo

  Apr 23, 2025      2m      0   
 

Tut 18: Button @ form view

Thêm button cho form view trong Odoo

Odoo Tut 18: Button @ form view

Trước khi xem bài viết này, bạn vui lòng hoàn thành hướng dẫn ở Tut 14: Search, Filter, Group By trong Odoo để tiếp tục tutorial tích hợp thêm button cho form view trong Odoo.

Bài viết này sẽ hướng dẫn bạn:

  • Cách thêm mới một nút nhấn (button) giao diện biểu mẫu (form) trong Odoo.
  • Các vị trí button thường đặt trong form view:
    • Button đặt ở header để thay đổi trạng thái
    • Button đặt ở đầu sheet để thống kê thông tin
    • Button đặt như một trường trong biểu mẫu (trường hợp này ít dùng)
  • Cách hiện thực hành động thực thi tương ứng cho các button này.

Code mẫu hoàn chỉnh việc thêm button vào form view trong Odoo bạn có thể tải về ở cuối bài viết

Môi trường lập trình:

  • Ubuntu
  • Python 3
  • Odoo 13 (released 2019)

Tham khảo bài viết sau để dựng môi trường lập trình Odoo: Tut 2: Hướng dẫn cài đặt Odoo

odoo form view buttons

Thêm button vào form view

Button#1. Thêm các button vào header

Vị trí button ở header của form view thường cho phép user thay đổi trạng thái (state) của record. Đối với vị trí này ta bổ sung thêm tag "header" vào trong thẻ "form" và trước thẻ "sheet".

Trong bối cảnh module quản lý thú cưng của chúng ta, Minh sẽ hiện thực nút bán thú :))) … thực ra đơn giản là cập nhật trạng thái thú cưng đã bán, và thêm 1 button khác để đảo ngược trạng thái đã bán thú là "In Store" để thể hiện thú cưng vẫn còn trong cửa hàng => đây cũng sẽ là trạng thái mặc định khi tạo một "record" thú cưng mới.

addons/mypet/views/my_pet_views.xml

<?xml version="1.0" encoding="UTF-8"?>
<odoo>
    <data>
        <record id="my_pet_form_view" model="ir.ui.view">
            <field name="name">my.pet.form.view</field>
            <field name="model">my.pet</field>
            <field name="arch" type="xml">
                <form>
                    <!-- Thêm đoạn block header này vào để được Button#1 -->
                    <header>
                        <button name="btn_sell_pet" type="object"
                            string="Sell Pet" class="oe_highlight"
                            attrs="{'invisible': [('state', '=', 'sold')]}"/>
                        <button name="btn_in_store" type="object"
                            string="In Store" class="oe_default"
                            attrs="{'invisible': [('state', '=', 'in_store')]}"/>
                        <field name="state" widget="statusbar"/>
                    </header>
                    <sheet>
                        <!-- ... -->
                    </sheet>
                </form>
            </field>
        </record>
    </data>
</odoo>

2. Thêm button để thể hiện thông tin (button box)

Nút bấm này thường để hiển thị nhanh thông tin (ví dụ: sản phẩm này đã bán bao nhiêu cái, và khi click vào nút thông tin này nó sẽ hiện ra danh sách đơn hàng của sản phẩm đang xem).

addons/mypet/views/my_pet_views.xml

<?xml version="1.0" encoding="UTF-8"?>
<odoo>
    <data>
        <record id="my_pet_form_view" model="ir.ui.view">
            <field name="name">my.pet.form.view</field>
            <field name="model">my.pet</field>
            <field name="arch" type="xml">
                <form>
                    <header>
                        <!-- ... -->
                    </header>
                    <sheet>
                        <!-- Thêm đoạn block div này vào để được Button#2 -->
                        <div class="oe_button_box" name="button_box">
                            <button type="object" name="action_owner_stat" class="oe_stat_button" icon="fa-book">
                                <field name="number_pets" string="Num Pets" widget="statinfo"/>
                            </button>
                        </div>
                        <!-- ... -->
                    </sheet>
                </form>
            </field>
        </record>
    </data>
</odoo>

3. Thêm button vào giữa form để thực hiện một hành động

Cái này Minh không cũng không biết phải mô tả sao cho phù hợp, nhưng đại loại là thêm một button vào để cho người dùng bấm, và khi bấm vào sẽ thực thi một hành động nào đó mình tự customize như cập nhật form chẳng hạn.

addons/mypet/views/my_pet_views.xml

<?xml version="1.0" encoding="UTF-8"?>
<odoo>
    <data>
        <record id="my_pet_form_view" model="ir.ui.view">
            <field name="name">my.pet.form.view</field>
            <field name="model">my.pet</field>
            <field name="arch" type="xml">
                <form>
                    <header>
                        <!-- ... -->
                    </header>
                    <sheet>
                        <!-- ... -->
                        <group name="images">
                            <group>
                                <!-- ... -->
                            </group>
                            <group>
                                <field name="dob"/>
                                <field name="gender"/>
                                <!-- Ta thêm Button#3 ở đây nè, dưới trường Gender, thực ra muốn đặt ở đâu là ta đặt -->
                                <button name="btn_set_default_values" type="object" string="Set default values" class="oe_highlight"/>
                            </group>                            
                        </group>
                        <!-- ... -->
                    </sheet>
                </form>
            </field>
        </record>
    </data>
</odoo>

Hiện thực hành động của các button trong model

Ta sẽ hiện thực "logic" của button sẽ hành động làm gì bằng cách định nghĩa phương thức trong model. Tên của phương thức trong model chính là giá trị của trường "name" đã khai báo button trong form file .xml nêu trên.

Như vậy, ta sẽ cần hiện thực các phương thức btn_sell_pet(), btn_in_store(), action_owner_stat(), btn_set_default_values() trong model "my.pet".

  • btn_sell_pet(): set trạng thái qua 'sold' (đã bán thú);
  • btn_in_store(): set trạng thái qua 'in_store' (thú còn trong cửa hàng);
  • action_owner_stat(): trả về action list view lọc với "domain" là theo "Owner" hiện tại;
  • btn_set_default_values(): thiết lập các giá trị mặc định cho các trường.

Đợt bổ sung button này ta sẽ thay đổi trạng thái của record, do đó, ta cũng bổ sung thêm field "state" (xem code bên dưới); Và trường thông tin "num_pets" sẽ được tính toán để thể hiện số lượng pet sở hữu bởi owner => nên ta cũng sẽ khai báo field "num_pets" và hiện thực hàm computed tương ứng.

addons/mypet/models/my_pet.py

# -*- coding: utf-8 -*-
from odoo import api, fields, models, tools, _
from odoo.exceptions import UserError, ValidationError

from odoo.http import request
import logging
_logger = logging.getLogger(__name__)

class MyPet(models.Model):
    _name = "my.pet"
    _description = "My pet model"

    # ... cac field khac da hien thuc truoc do ...

    state = fields.Selection([
        ('in_store', 'In Store'),
        ('sold', 'Sold')
    ], string='State', default='in_store')
    number_pets = fields.Integer(string='Number of pets owned by Owner', compute='_compute_number_pets')
    
    def _compute_number_pets(self):
        for record in self:
            if record.owner_id:
                pets = self.search([('owner_id', '=', record.owner_id.id)])
                if pets:
                    record.number_pets = len(pets)
                else:
                    record.number_pets = 0
            else:
                record.number_pets = 0
            pass
    
    # ... cac phuong thuc khac da hien thuc truoc do ...
    # ... them vao cuoi ...

    def btn_sell_pet(self):
        self.state = 'sold'
        pass
        
    def btn_in_store(self):
        self.state = 'in_store'
        pass
        
    def action_owner_stat(self):
        self.ensure_one()
        action = self.env.ref('mypet.action_my_pet').read()[0]
        action.update({
            'domain': [('owner_id', '=', self.owner_id.id)],
        })
        return action

    def btn_set_default_values(self):
        self.write({
            'name': 'Kitty Cat',
            'basic_price': 450000,
            'age': 2,
            'weight': 5.3,
            'gender': 'male',
        })
        pass    

Cập nhật vào Odoo

Sau khi hiện thực view và model, ta tiến hành restart Odoo và update addon "My pet - minhng.info" (aka. "mypet").

odoo form view button added

Nhấn nút các nút button để kiểm tra logic đã chạy ổn.

odoo button sell pet change stat0e

odoo button box

Code Download

Code mẫu hoàn chỉnh Tut 18: mypet_250423.zip

Hãy tham gia group Facebook để trao đổi và học hỏi thêm về Odoo nhé các bạn => Khám phá Odoo: https://facebook.com/groups/odoo-dev


Cài đặt Odoo:

Danh sách bài viết series Odoo:

Tham gia ngay group trên Facebook để cùng thảo luận với đồng bọn nhé:

Khám phá Odoo


Khám phá xử lý ảnh - GVGroup




-->