View trong Odoo
Tut 4: 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 3 để có được model Thú cưng (mypet) trong Odoo. Bài viết này sẽ hướng dẫn bạn cách tạo view tương ứng cho model để thể hiện trên giao diện.
Mã nguồn hoàn chỉnh cho bài viết này được đính kèm ở cuối bài viết.
Tạo view trong Odoo
Phân quyền cho model
Tạo file đặc tả phân quyền access model và đăng ký vào manifest của module.
- mypet/security/ir.model.access.csv: tạo mới file csv trong thư mục security, mô tả group user nào có những quyền hạn nào đối với model mới của mình my.pet
- mypet/__manifest__.py: đăng ký đường dẫn tương đối đến file security vừa tạo ở trên, trong field data
Cụ thể hiện thực code như sau:
mypet/security/ir.model.access.csv
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_my_pet,access_my_pet,model_my_pet,base.group_user,1,1,1,1
Để đơn giản hóa, mình đăng ký mọi user có quyền access model my.pet này.
- Cột id và name: tên tự đặt, convention thường là access_TÊN_MODEL. _TÊN_MODEL thường được encode bằng cách replace dấu chấm thành shift gạch. Ví dụ: "my.pet" -> "my_pet", "sale.order.line" thành "sale_order_line".
- Cột model_id: có format model_TÊN_MODEL.
- Cột group_id:id - trong Odoo sẽ có một số group người dùng đã được định nghĩa sẵn (built-in) hoặc bạn tự định nghĩa thêm. Trong cột này mình để ID của group user này. Format là TÊN_MODULE.TÊN_GROUP. Code trên mình dùng là "base.group_user", tức trong module "base" Odoo đã có định nghĩa một group "group_user" này rồi.
- Cột perm_read, perm_write, perm_create, perm_unlink: cho phép ta đặc tả permission có quyền đọc, ghi, tạo, xóa hay không. Giá trị 1 là quyền, 0 là không có quyền. Để đơn giản, mình kích hết là 1 luôn, hehe ^^.
mypet/__manifest__.py
...
'data': [
'security/ir.model.access.csv',
],
...
Tạo menu, tree view và form view cho model
Sau khi đăng ký phân quyền access cho model, ta tiếp tục tạo view trong Odoo và đăng ký manifest cho view này.
- mypet/views/my_pet_views.xml: Odoo sử dụng XML để mô tả view. Do đó, bạn thường xuyên đọc code Odoo để hiểu rõ cú pháp này.
- mypet/__manifest__.py: đăng ký đường dẫn tương đối đến file view vừa tạo ở trên, trong field data
mypet/__manifest__.py
...
'data': [
'security/ir.model.access.csv',
'views/my_pet_views.xml',
],
...
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>
<sheet>
<div class="oe_title">
<label for="name" string="Pet Name" class="oe_edit_only"/>
<h1><field name="name" placeholder="e.g. Kittie"/></h1>
<label for="owner_id"/>
<h3><field name="owner_id"/></h3>
</div>
<group name="images">
<group>
<field name="age"/>
<field name="weight"/>
</group>
<group>
<field name="dob"/>
<field name="gender"/>
</group>
</group>
<notebook>
<page name="general_information" string="General Information">
<group>
<group>
<field name="nickname"/>
</group>
<group>
<label for="description" colspan="2"/>
<field name="description" colspan="2" nolabel="1"/>
</group>
</group>
</page>
<page name="additional_information" string="Additional Information">
<group>
<group string="Images">
<field name="pet_image" string="Pet's Image" widget="image"/>
</group>
<group string="Products">
<field name="product_ids" widget="many2many_tags"/>
</group>
</group>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record id="my_pet_tree_view" model="ir.ui.view">
<field name="name">my.pet.tree.view</field>
<field name="model">my.pet</field>
<field name="arch" type="xml">
<tree string="Pets" default_order="create_date desc">
<field name="name"/>
<field name="nickname"/>
<field name="age"/>
<field name="weight"/>
<field name="dob"/>
<field name="gender"/>
<field name="owner_id"/>
</tree>
</field>
</record>
<record id="action_my_pet" model="ir.actions.act_window">
<field name="name">My Pet</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">my.pet</field>
<!-- <field name="view_type">form</field> --> <!-- Odoo 13 has removed this field -->
<field name="view_ids" eval="[(5, 0, 0),
(0, 0, {'view_mode': 'tree', 'view_id': ref('my_pet_tree_view')}),
(0, 0, {'view_mode': 'form', 'view_id': ref('my_pet_form_view')})]"/>
</record>
<menuitem id="menu_my_pet"
name="My Pet"
action="action_my_pet"
sequence="10"
groups="base.group_user"/>
</data>
</odoo>
Cập nhật ngày 11/04/2020:: từ Odoo 13 đã bỏ trường "view_type", do đó trong view mình không dùng trường này nữa nha. Odoo 12 trở xuống mới dùng trường này.
Giải thích view XML trên:
- Đăng ký Menu @ menuitem:
- id (unique), name là tên tự đặt
- action link đến một act_window có id như đặc tả (action_my_pet)
- sequence là thứ tự ưu tiên của menu (priority), giá trị càng nhỏ thì độ ưu tiên càng cao, nhiều menu thì sequence nhỏ sẽ được đứng trước
- groups mô tả group user nào có quyền thấy menu này.
- Đăng ký action @ record id="action_my_pet"
- name là tên tự đặt
- res_model ref đến tên model
- view_ids mình ref đến tree view và form view.
- Đăng ký tree view @ record id="my_pet_tree_view":
- Trong Odoo gọi là tree view nhưng ta có thể hiểu nó là "list view"
- name là tên tự đặt
- model ref đến tên model
- Thẻ tree ta có đặc tả default_order="create_date desc" tức sẽ show list sắp xếp record theo thứ tự giảm dần ngày tạo (mới -> cũ)
- Bên trong chứa các field, name của field sẽ link / reference đến các field trong model my.pet đã tạo trong @ mypet/models/my_pet.py
- Đăng ký form view @ record id="my_pet_form_view":
- name là tên tự đặt
- model ref đến tên model
- Bên trong form ta có thể tạo các group
- Các field có name cũng reference đến các trường trong model
- Ngoài ra, thuộc tính của thẻ field ta cũng có thể dùng widget để nó render theo chủ đích mong muốn. Odoo có nhiều widget built-in mà ta có thể dùng ngay hoặc tự mình customize. Lưu ý, widget cũng phải phù hợp với field type đã đặc tả trong model.
Tiếp theo, mình phải apply code XML vào Odoo theo chỉ dẫn ở mục tiếp theo bên dưới.
Upgrade module trong Odoo
Lưu ý rằng khi chỉnh sửa hoặc tạo mới view (liên quan đếp XML), để apply code vào server ta phải UPGRADE module đó. Cách upgrade ta làm như sau:
- Bật debug / developer mode: đã hướng dẫn ở Tut 3.
- Sau đó chọn module và nhấn "Upgrade".
Sau khi làm theo các bước trong bài viết này bạn đã tự mình tạo được view trong Odoo cho module customize rồi đấy. Kết quả menu & view XML Minh đã tạo sẽ render như sau:
Source code download: Tut 4
Chuyên mục thảo luận cho Tut 4 @ https://www.facebook.com/groups/odoo.dev/learning_content/?filter=226430075118574&post=799274220537616
- Khóa học lập trình Odoo TP.HCM: Thông tin và đăng ký khóa học
- Khảo sát nhu cầu học nghiệp vụ Odoo Offline @ HCM & đăng ký sớm: https://forms.gle/auBXLNbfuNqhJSbj8
Cài đặt Odoo:
- Docker Compose for Odoo 10
- Docker Compose for Odoo 11
- Docker Compose for Odoo 12
- Docker Compose for Odoo 13
- Docker Compose for Odoo 14
- Docker Compose for Odoo 15
- Docker Compose for Odoo 16
Danh sách bài viết series Odoo:
- Tut 0: Học lập trình Odoo - tutorials
- Tut 1: Odoo là gì?
- Tut 2: Hướng dẫn cài đặt Odoo version 10, 11, 12, 13
- Tut 3: Tạo model trong Odoo
- Tut 4: View trong Odoo
- Tut 5: Controller trong Odoo
- Tut 6: Thừa kế model trong Odoo
- Tut 7: Thừa kế view trong Odoo
- Tut 8: Thừa kế controller trong Odoo
- Tut 9: API trong Odoo - XML-RPC
- Tut 10: Hiện thực wizard trong Odoo
- Tut 11: Tạo widget trong Odoo
- Tut 12: Tạo settings trong Odoo cho custom addon
- Tut 13: Thêm button cho list/tree view trong Odoo
- Tut 14: Search, Filter, Group By trong Odoo
- Tut 15: Kết nối PostgreSQL database của Odoo bằng câu lệnh
- Tut 16: Kết nối pgAdmin vào PostgreSQL database của Odoo
Tham gia ngay group trên Facebook để cùng thảo luận với đồng bọn nhé:
- Fanpage Minh: https://www.facebook.com/minhng.info
- Khám phá Odoo: https://www.facebook.com/groups/odoo-dev
Khám phá Odoo