Nhảy đến nội dung

Chương 4 - Model và các trường cơ bản

Ở bài trước, chúng ta đã có thể tạo một Odoo mô đun. Tuy nhiên mô đun này vẫn đang trống, và chưa cho lưu dữ liệu. Ở mô đun bất động sản, chúng ta muốn lưu thông tin liên quan tới bất động sản như tên, mô tả, giá bán, khu vực sống vào một CSLD. Odoo khung phần mềm cung cấp các công cụ để hỗ trợ tương tác với CSDL. 

Mô đun estate mới chỉ có 2 file là __init_.py và __manifest__.py

So sánh với một mô đun hoàn chỉnh crm, thì crm có nhiều thư mục khác.

Mô đun CRM ngoài 2 file là file __init__.py__manifest__.py còn có nhiều thư mục khác

Kiểm tra lại lần nữa mô đun estate đã được cài đặt và nó xuất hiện trong phần danh sách App đã cài.  

Lưu ý: 

Không sử dụng biến toàn cục có thể thay đổi (mutable global variables). Vì sao? một Odoo có thể chạy trên nhiều CSLD song song với cùng một bộ xử lý Python. Những mô đun riêng biệt có thể cài trên mỗi CLSD, do đó chung ta không thể lệ thuộc vào biến cục bộ mà biến đó có thể được cập nhật tuỳ theo mô đun đã cài. 

Object-Relational Mapping (ORM)

Ghi chú ở cuối chương bạn có thể tạo bảng estate_property

$ psql -d rd-demo
rd-demo=# SELECT COUNT(*) FROM estate_property;
count
-------
    0
(1 row)

Thành phần quan trọng của Odoo chính là lớp ORM. Lớp này tránh được việc phải viết thủ công các lệnh SQL và cung cấp dịch vụ mang tính bảo mật (an ninh) và mở rộng.

Các đối tượng kinh doanh được khai báo là các lớp Python mở rộng từ Model, nên chúng sẽ được tích hợp vào hệ thống tự động ổn định. Như vậy một đối tượng kinh doanh chính là một model vì nó là lớp Python (Python class) mở rộng từ Model.

Chúng ta có thể lên cấu hình các model bằng các thuộc tính trong định nghĩa của nó, ví dụ thuộc tính quan trọng của model là _name, định nghĩa tên của model trong hệ thống Odoo. Đây là định nghĩa tối thiểu của một model. 

from odoo import models
class TestModel(models.Model):
    _name = "test_model"

Ở đây chúng ta có một Python class TestModel, class này là mở rộng từ Model (models.Model), sau đó khai báo thuộc tính quan trọng chính là tên _name, là "test_model". 

Định nghĩa này đủ để ORM tạo một bảng trên CSLD với tên test_model, theo thông lệ tất các các models được đặt ở trong thư mục models và mỗi model được định nghĩa bằng file Python của chính nó. 

Ví dụ: crm.recurring.plan là một model đặt trong thư mục models của crm mô đun. Model có tên là crm.recurring.planđược định nghĩa bằng file Python là crm_recurring_plan.py. ORM sẽ tạo một bảng trong CSLD với tên crm_recurring_plan.

odoo/addons/crm/models/crm_recurring_plan.py

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models
class RecurringPlan(models.Model):
   _name = "crm.recurring.plan"

Trong file này, tên của model được khai báo với tên là "crm.recurring.plan", còn tên file python là crm_recurring_plan.

addons/crm/models/__init__.py

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import res_users
from . import calendar
from . import crm_lead
from . import crm_lost_reason
from . import crm_stage
from . import crm_team
from . import res_config_settings
from . import res_partner
from . import digest
from . import crm_lead_scoring_frequency
from . import utm
from . import crm_recurring_plan

addons/crm/__init__.py

File này bạn sẽ thêm một số class sẵn có trong Odoo.

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import controllers
from . import models
from . import report
from . import wizard
from odoo import api, SUPERUSER_ID

Như vậy bảng crm_recurring_plan được định nghĩa bằng file crm_recurring_plan.py và file này được nhập trong __init__.py. Trong khi đó thư mục models được nhập trong file __init__.py, như sau. 

  1. model được định nghĩa trong crm/models/crm_recurring_plan.py 
  2. file crm_recurring_plan.py được nhập vào crm/models/__init__.py 
  3. Tệp models được nhập vào crm/__init__.py 

Giờ bạn sẽ làm tương tự với mô đun estate. 

Vào thư mục chứa mô đun estate sau đó thêm thư mục models, tạo một file trống estate_property.py, rồi thêm các thuộc tính của model như tên (_name) và mô tả (_desciption)

from odoo import models
class EstateProperty(models.Model):
_name = "estate.property"
_description = "Bat dong san"

Tiếp tục tạo thêm một file __init__.py trong thư mục models. File này chúng ta chỉ nhập file estate_property (không có đuôi .py) mà không phải import tên của model là estate.property.

# -*- coding: utf-8 -*-
from . import estate_property

Khi có bất kỳ sửa đổi nào ở các file Python bạn cần khởi động lại server, khi khởi động lại server chúng ta dùng các biến -d và -u. 

./odoo-bin --addons-path="addons/,../tutorials" -d rd-demo -u estate

Sử dụng -u estate để nâng cấp mô đun estate. ORM sẽ áp những thay đổi schema CSDL. Trong trường hợp này nó sẽ tạo một bảng (estate_property) mới trên cơ sở dữ liệu. Bạn có thể kiểm tra bằng 

psql -d rd-demo

SELECT COUNT(*) FROM estate_property;

Kết quả

 count 
------- 
    0 
(1 row)

Hoặc có thể kiểm tra bằng /dt

 -d rd-demo nghĩa là nâng cấp mô đun thực hiện trên CLSD rd-demo, -u nên luôn được sử dụng kết hợp với -d, tức là khi có cập nhật nào đó thì phải chỉ ra CSDL mà bạn muốn cập nhật. 

Lưu ý bạn cần để khởi động CSLD.

. venv/bin/activate

./odoo-bin --addons-path="addons/,../tutorials" -d rd-demo

Nếu gặp lỗi sau khi cập nhật MAC M1.

psql: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such file or directory

Bạn có thể cài.

brew install postgresql@14

Trường của Model

Sử dụng trường để định nghĩa model có thể lưu cái gì và nơi chúng được lưu trữ. Trường được định nghĩa là các thuộc tính trong lớp model. 

Ví dụ 

from odoo import fields, models

class TestModel(models.Model):
    _name = "test_model"
    _description = "Test Model"

    name = fields.Char()

Trường name là một Char, đại diện cho một Python str (unicode) và một SQL VARCHAR.

Có 2 danh mục cho trường: Trường đơn giản, lưu các giá trị hạt nhân lên bảng của model và trường liên hệ, liên kết các bản ghi (của cùng một model hay các mode khác nhau)

Các trường đơn giản bao gồm Boolean, Float, Char, Text, Date và Selection.

Bây giờ bạn sẽ thêm các field vào bảng 

FieldType
nameChar
descriptionText
postcodeChar
date_availabilityDate
expected_priceFloat
selling_priceFloat
bedroomsInteger
living_areaInteger
facadesInteger
garageBoolean
gardenBoolean
garden_areaInteger
garden_orientationSelection
from odoo import fields, models


class EstateProperty(models.Model):
    _name = "estate.property"
    _description = "Bat dong san"

    name = fields.Char()
    description = fields.Text()
    postcode = fields.Char()
    date_availability = fields.Date()
    expected_price = fields.Float()
    selling_price = fields.Float()
    bedrooms = fields.Integer()
    living_area = fields.Integer()
    facades = fields.Integer()
    garage = fields.Boolean()
    garden = fields.Boolean()
    garden_area = fields.Boolean()
    garden_orientation = fields.Selection(
        string = 'Type',
        selection=[('north', 'North'), ('south', 'South'), ('east', 'East'), ('west', 'West')]
    )

Sau khi thêm các trường.

Trường garden_orientation có 4 giá trị 'North', 'South', 'East', 'West'. Danh sách lựa chọn được định nghĩa là một danh sách tuples.

Ở đây selection chỉ ra giá trị có thể có cho trường, ở ví dụ trên selection là một danh sách các turple chứa cặp (giá trị và nhãn - value label). 

Trường tự động

You may have noticed your model has a few fields you never defined. Odoo creates a few fields in all models. These fields are managed by the system and can’t be written to, but they can be read if useful or necessary:

Có vài trường Odoo tự động tạo trong tất các các model. Những trường này quản lý bằng hệ thống và không thể bị ghi đè, nhưng chúng có thể được đọc nếu cần thiết.

id (Id)

Nhận diện bản ghi của model.

create_date (Datetime)

Ngày tạo bản ghi.

create_uid (Many2one)

Người dùng tạo bản ghi.

write_date (Datetime)

Last modification date of the record. Ngày chỉnh sửa bản ghi lần cuối.

write_uid (Many2one)

Người dùng cuối chỉnh sửa bản ghi.
 

Môt số thuộc tính sẵn có cho tất cả các fields. Đây là thuộc tính phổ biến nhất. 

string (str, default: field’s name)

Nhãn của trường trong giao diện người dùng (người dùng có thể nhìn thấy). Mặc định là tên của trường

required (bool, default: False)

Nếu thiết lập là True, thì trường không thể để trống. Nó phải là gía trị mặc định hoặc luôn là một giá trị đưa ra khi tạo một bản lưu. Mặc định là False

help (str, default: '')

Cung cấp thông tin hỗ trợ cho người dùng về trường.

index (bool, default: False)

Yêu cầu Odoo tạo một index CSLD vào cột. Mặc định là False. 

Back to the course
Lecture Course

Phát Triển Odoo Mô Đun

Giá
1.000.000 ₫
Category
Thời gian khóa học
Trình độ
Cơ bản
Giá
Giá
1.000.000 ₫
Phát Triển Odoo Mô Đun
Lessons Of Course

Tài liệu