Thừa kế view trong Odoo

  May 27, 2020      2m
   

Tut 7: Thừa kế view trong Odoo

Thừa kế view trong Odoo

Trước khi xem bài viết này, bạn vui lòng hoàn thành hướng dẫn ở Tut 6 - Thừa kế model trong Odoo hoặc download mã nguồn ở cuối bài Tut 6.

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

  • Thừa kế view trong Odoo.
  • Sử dụng view thừa kế.
  • Chỉnh sửa view bằng cách thừa kế.

Mã nguồn hoàn chỉnh cho bài viết Tut 7 này được đính kèm ở cuối bài viết.

Thừa kế view trong Odoo

Thừa kế view để chỉnh sửa, bổ sung view của module đã cung cấp thực sự quan trọng. Ta không nên sửa trực tiếp view file XML của module gốc, mà phải tiến hành thông qua thừa kế. Lợi điểm của việc chỉnh sửa bổ sung thông qua thừa kế:

  • Các chỉnh sửa bổ sung sẽ nằm gọn trong module mới mà ta đang phát triển.
  • Gỡ bỏ module mới đồng thời sẽ gỡ bỏ các thừa kế, khiến view trở về nguyên trạng => flexible!

Thêm field vào view cũ bằng cách thừa kế

Như ở tut 6, sau khi thêm field:

toy = fields.Char('Pet Toy', required=False)

Rõ ràng nếu mình không chỉnh sửa view trực tiếp trong file xml của module mypet thì field mới thừa kế model ở module mypet_plus sẽ không được hiển thị. Do đó mình sẽ tiến hành hiện thực thừa kế view trong module mypet_plus để thêm việc hiển thị field mới này.

Thừa kế trong Odoo được hiện thực bằng cách:

  • View con này ta đặt IDname mới, attribute model trỏ tới đúng model my.pet.
  • Đặc tả inherit_id reference đến ID của view cha ta sẽ thừa kế. Cú pháp reference: . => ví dụ: **mypet.my_pet_form_view** (bạn có thể mở source code của module **mypet** để xem lại định nghĩa view mình đã viết ở các tút trước).
  • Ta dùng XPATH để tham chiếu tới node cần thay đổi / chỉnh sửa trong view cha. XPATH các bạn vui lòng tự tìm kiếm tài liệu và bổ sung kiến thức cho phần này nếu chưa nắm rõ nha. Mình không hướng dẫn cách viết theo cú pháp xpath trong bài viết này.
  • Chọn kiểu mà ta sẽ chỉnh sửa / thay đổi phù hợp. Thuộc tính position hỗ trợ các lựa chọn: inside, replace, after, before, attributes, move. Trong ví dụ cụ thể dưới mình sử dụng position inside để chèn 1 node mới vào vị trí cuối cùng trong node "group".

mypet_plus/views/my_pet_views.xml

<?xml version="1.0" encoding="UTF-8"?>
<odoo>
    <data>
        <record id="mypet_plus_my_pet_form_view" model="ir.ui.view">
            <field name="name">mypet.plus.my.pet.form.view</field>
            <field name="model">my.pet</field>
            <field name="inherit_id" ref="mypet.my_pet_form_view"/>
            <field name="arch" type="xml">
                <xpath expr="//group[@name='images']/group[2]" position="inside">
                    <field name="toy"/>
                </xpath>
            </field>
        </record>
    </data>
</odoo>

Đừng quên thêm field vào manifest và upgrade module để cập nhật view nhé!

mypet_plus/__manifest__.py

# -*- coding: utf-8 -*-
{
    ...
    'data': [
        ...
        'views/my_pet_views.xml', # <- them dong nay :D
    ],
    ...
}

Upgrade module mypet_plus để xem kết quả field mới đã được thêm thành công:

Thừa kế xóa field trong view

Giả sử mình thấy field product thực sự không liên quan gì đến thông tin về thú cưng của mình. Mình muốn dùng thừa kế để xóa field đó đi khỏi view mà không cần chỉnh sửa trực tiếp file XML trong module gốc (mypet).

Ta có thể làm như sau:

mypet_plus/views/my_pet_views.xml

<?xml version="1.0" encoding="UTF-8"?>
<odoo>
    <data>
        <record id="mypet_plus_my_pet_form_view" model="ir.ui.view">
            <field name="name">mypet.plus.my.pet.form.view</field>
            <field name="model">my.pet</field>
            <field name="inherit_id" ref="mypet.my_pet_form_view"/>
            <field name="arch" type="xml">
                <xpath expr="//group[@name='images']/group[2]" position="inside">
                    <field name="toy"/>
                </xpath>
                <xpath expr="//field[@name='product_ids']" position="replace">
                    <!-- empty -->
                </xpath>
            </field>
        </record>
    </data>
</odoo>

Sau khi upgrade module mypet_plus, ta sẽ thấy field product biến mất :D.

Thừa kế thêm node vào phía trước hoặc sau trong view

Ta sử dụng position "before" hoặc "after" tùy nhu cầu. Nó sẽ giúp chèn node mới của ta vào liền trước hay liền sau node mà ta đang tham chiếu.

<xpath expr="<cú-pháp-xpath-tham-chiếu-đến-node-trong-view-cha>" position="before">
    <field name="..."/>
    <!-- ... -->
</xpath>
<xpath expr="<cú-pháp-xpath-tham-chiếu-đến-node-trong-view-cha>" position="after">
    <field name="..."/>
    <!-- ... -->
</xpath>

Mình không cung cấp ví dụ cụ thể trong mục này, xem như đây là một bài tập nhỏ mà bạn có thể tự làm nếu nghĩ ra ý tưởng cần dùng đến nha :).

Thừa kế thay đổi thuộc tính

Trường hợp thường dùng là ẩn field đi trong trường hợp không nên xóa hẳn field khỏi view.

Giả sử mình muốn có thêm 2 chỉnh sửa attribute sau:

  • Ẩn field "Pet Description" đi
  • Đổi string của field "Nickname" thành "Pet Nick Name"

Ta có thể làm như sau:

mypet_plus/views/my_pet_views.xml

<?xml version="1.0" encoding="UTF-8"?>
<odoo>
    <data>
        <record id="mypet_plus_my_pet_form_view" model="ir.ui.view">
            <field name="name">mypet.plus.my.pet.form.view</field>
            <field name="model">my.pet</field>
            <field name="inherit_id" ref="mypet.my_pet_form_view"/>
            <field name="arch" type="xml">
                <xpath expr="//group[@name='images']/group[2]" position="inside">
                    <field name="toy"/>
                </xpath>
                <xpath expr="//field[@name='product_ids']" position="replace">
                    <!-- empty -->
                </xpath>
                <xpath expr="//field[@name='description']" position="attributes">
                    <attribute name="invisible">1</attribute> <!-- hide description field -->
                </xpath>
                <xpath expr="//label[@for='description']" position="attributes">
                    <attribute name="invisible">1</attribute> <!-- hide label of description field -->
                </xpath>
                <xpath expr="//field[@name='nickname']" position="attributes">
                    <attribute name="string">Pet Nick Name</attribute> <!-- change nickname field label to "Pet Nick Name" -->
                </xpath>
            </field>
        </record>
    </data>
</odoo>

Các hướng dẫn thừa kế view như trên là các thao tác THƯỜNG DÙNG nhất trong quá trình phát triển module của một Odoo developer!

Bạn có thể đọc thêm tài liệu về view của Odoo (cụ thể phần thừa kế) có thể tham khảo link bên dưới:

https://www.odoo.com/documentation/13.0/reference/views.html#inheritance-specs

Hẹn tiếp tục gặp lại mọi người ở bài viết tiếp theo - Tut 8: thừa kế controller trong Odoo

Download Odoo - Tut 7

Source code download: Tut 7 - Inheritance in views


minhng.info dự định sẽ mở khóa học training lập trình Odoo OFFLINE ở TP. HCM, nếu bạn nào có nhu cầu giúp mình tham gia khảo sát nhé.

https://forms.gle/K9t2kjx5SCQWftkm8

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é: