Chương 11: Thêm Những Điểm Nhấn

Our real estate module now makes sense from a business perspective. We created specific views, added several action buttons and constraints. However our user interface is still a bit rough. We would like to add some colors to the list views and make some fields and buttons conditionally disappear. For example, the 'Sold' and 'Cancel' buttons should disappear when the property is sold or canceled since it is no longer allowed to change the state at this point.

Chương này bao gồm một tập hợp con rất nhỏ về những gì có thể được thực hiện trong các khung nhìn. Đừng ngần ngại đọc tài liệu tham khảo để có cái nhìn tổng quan đầy đủ hơn.

Tham khảo: tài liệu liên quan đến chương này có thể được tìm thấy trong Xem bản ghiXem kiến trúc.

Lượt xem nội tuyến

Ghi chú

Mục tiêu: ở cuối phần này, danh sách thuộc tính cụ thể sẽ được thêm vào chế độ xem loại thuộc tính:

Chế độ xem danh sách nội tuyến

Trong mô-đun bất động sản, chúng tôi đã thêm danh sách các ưu đãi cho một bất động sản. Chúng tôi chỉ cần thêm trường offer_ids với:

<field name="offer_ids"/>

Trường này sử dụng chế độ xem cụ thể cho estate.property.offer. Trong một số trường hợp, chúng tôi muốn xác định chế độ xem danh sách cụ thể chỉ được sử dụng trong ngữ cảnh của chế độ xem biểu mẫu. Ví dụ: chúng tôi muốn hiển thị danh sách các thuộc tính được liên kết với một loại thuộc tính. Tuy nhiên, chúng tôi chỉ muốn hiển thị 3 trường cho rõ ràng: tên, giá dự kiến và trạng thái.

Để làm điều này, chúng ta có thể xác định chế độ xem danh sách nội tuyến. Chế độ xem danh sách nội tuyến được xác định trực tiếp bên trong chế độ xem biểu mẫu. Ví dụ:

from odoo import fields, models

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

    description = fields.Char()
    line_ids = fields.One2many("test_model_line", "model_id")


class TestModelLine(models.Model):
    _name = "test_model_line"
    _description = "Test Model Line"

    model_id = fields.Many2one("test_model")
    field_1 = fields.Char()
    field_2 = fields.Char()
    field_3 = fields.Char()
<form>
    <field name="description"/>
    <field name="line_ids">
        <tree>
            <field name="field_1"/>
            <field name="field_2"/>
        </tree>
    </field>
</form>

Trong chế độ xem biểu mẫu của test_model, chúng tôi xác định chế độ xem danh sách cụ thể cho test_model_line với các trường field_1field_2.

Bạn có thể tìm thấy một ví dụ tại đây.

Exercise

Thêm chế độ xem danh sách nội tuyến.

  • Thêm trường One2many property_ids vào mô hình estate.property.type.

  • Thêm trường trong chế độ xem biểu mẫu estate.property.type như được mô tả trong Mục tiêu của phần này.

Widget

Tham khảo: tài liệu liên quan đến phần này có thể được tìm thấy trong Lĩnh vực.

Ghi chú

Mục tiêu: ở cuối phần này, trạng thái của thuộc tính sẽ được hiển thị bằng một tiện ích cụ thể:

Tiện ích thanh trạng thái

Bốn trạng thái được hiển thị: Mới, Đã nhận được ưu đãi, Đã chấp nhận ưu đãi và Đã bán.

Bất cứ khi nào chúng tôi thêm các trường vào mô hình của mình, chúng tôi (gần như) không bao giờ phải lo lắng về việc các trường này trông như thế nào trong giao diện người dùng. Ví dụ: bộ chọn ngày được cung cấp cho trường Date và trường One2many được tự động hiển thị dưới dạng danh sách. SoOn chọn 'widget' phù hợp tùy thuộc vào loại trường.

Tuy nhiên, trong một số trường hợp, chúng tôi muốn một biểu diễn cụ thể của một trường có thể được thực hiện nhờ thuộc tính widget. Chúng tôi đã sử dụng nó cho trường tag_ids khi chúng tôi sử dụng thuộc tính widget="many2many_tags". Nếu chúng ta không sử dụng nó thì trường này sẽ hiển thị dưới dạng danh sách.

Mỗi loại trường có một bộ tiện ích có thể được sử dụng để tinh chỉnh hiển thị của nó. Một số vật dụng cũng có thêm tùy chọn. Bạn có thể tìm thấy danh sách đầy đủ trong Lĩnh vực.

Exercise

Sử dụng tiện ích thanh trạng thái.

Sử dụng tiện ích thanh trạng thái để hiển thị `` trạng thái`` của estate.property như được mô tả trong Mục tiêu của phần này.

Mẹo: bạn có thể tìm thấy một ví dụ đơn giản tại đây.

Cảnh báo

Cùng một trường nhiều lần trong một chế độ xem

Chỉ thêm trường một lần vào danh sách hoặc dạng xem biểu mẫu. Việc thêm nó nhiều lần không được hỗ trợ.

Danh sách đơn đặt hàng

Tham khảo: tài liệu liên quan đến phần này có thể được tìm thấy trong Người mẫu.

Ghi chú

Mục tiêu: ở cuối phần này, tất cả các danh sách sẽ hiển thị theo mặc định theo thứ tự xác định. Các loại tài sản có thể được đặt hàng bằng tay.

Trong các bài tập trước, chúng ta đã tạo một số dạng xem danh sách. Tuy nhiên, chúng tôi không chỉ định thứ tự các bản ghi phải được liệt kê theo mặc định. Đây là một điều rất quan trọng đối với nhiều trường hợp kinh doanh. Ví dụ: trong mô-đun bất động sản của chúng tôi, chúng tôi muốn hiển thị các ưu đãi cao nhất ở đầu danh sách.

Người mẫu

SoOn cung cấp một số cách để đặt thứ tự mặc định. Cách phổ biến nhất là xác định thuộc tính _order trực tiếp trong mô hình. Bằng cách này, các bản ghi được truy xuất sẽ tuân theo một thứ tự xác định nhất quán trong tất cả các chế độ xem kể cả khi các bản ghi được tìm kiếm theo chương trình. Theo mặc định không có thứ tự nào được chỉ định, do đó các bản ghi sẽ được truy xuất theo thứ tự không xác định tùy thuộc vào PostgreSQL.

Thuộc tính _order nhận vào một chuỗi chứa danh sách các trường sẽ được sử dụng để sắp xếp. Nó sẽ được chuyển đổi thành mệnh đề order_by trong SQL. Ví dụ:

from odoo import fields, models

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

    description = fields.Char()

Hồ sơ của chúng tôi được sắp xếp theo id giảm dần, nghĩa là cao nhất sẽ đến trước.

Exercise

Thêm thứ tự mô hình.

Xác định các thứ tự sau trong các mô hình tương ứng của chúng:

Người mẫu

Đặt hàng

bất động sản.tài sản

ID giảm dần

bất động sản.property.offer

Giá giảm dần

bất động sản.property.tag

Tên

bất động sản.property.type

Tên

Xem

Có thể đặt hàng ở cấp độ mô hình. Điều này có ưu điểm là có thứ tự nhất quán ở mọi nơi danh sách bản ghi được truy xuất. Tuy nhiên, cũng có thể xác định trực tiếp một thứ tự cụ thể trong một chế độ xem nhờ thuộc tính default_order (example).

Thủ công

Cả thứ tự mô hình và chế độ xem đều cho phép sự linh hoạt khi sắp xếp các bản ghi, nhưng vẫn còn một trường hợp chúng ta cần đề cập đến: thứ tự thủ công. Người dùng có thể muốn sắp xếp các bản ghi tùy thuộc vào logic nghiệp vụ. Ví dụ: trong mô-đun bất động sản, chúng tôi muốn sắp xếp các loại thuộc tính theo cách thủ công. Thực sự hữu ích khi có những loại được sử dụng nhiều nhất xuất hiện ở đầu danh sách. Nếu công ty bất động sản của chúng tôi chủ yếu bán nhà thì việc để 'Nhà' xuất hiện trước 'Căn hộ' sẽ thuận tiện hơn.

Để làm như vậy, trường chuỗi được sử dụng kết hợp với tiện ích xử . Rõ ràng trường sequence phải là trường đầu tiên trong thuộc tính _order.

Exercise

Thêm đặt hàng thủ công.

  • Thêm trường sau:

Người mẫu

Cánh đồng

Kiểu

bất động sản.property.type

Sự liên tiếp

số nguyên

  • Thêm chuỗi vào chế độ xem danh sách estate.property.type với tiện ích chính xác.

Mẹo: bạn có thể tìm thấy ví dụ tại đây: modelview.

Thuộc tính và tùy chọn

Sẽ rất khó để trình bày chi tiết tất cả các tính năng có sẵn cho phép tinh chỉnh giao diện của chế độ xem. Vì vậy, chúng tôi sẽ tập trung vào những cái phổ biến nhất.

Hình thức

Ghi chú

Mục tiêu: ở cuối phần này, chế độ xem biểu mẫu thuộc tính sẽ có:

  • Hiển thị có điều kiện các nút và trường

  • Màu thẻ

Chế độ xem biểu mẫu có rắc

Trong mô-đun bất động sản, chúng tôi muốn sửa đổi hoạt động của một số trường. Ví dụ: chúng tôi không muốn có thể tạo hoặc chỉnh sửa loại thuộc tính từ chế độ xem biểu mẫu. Thay vào đó, chúng tôi mong đợi các loại sẽ được xử lý trong menu thích hợp của chúng. Chúng tôi cũng muốn cung cấp cho các thẻ một màu sắc. Để thêm các tùy chỉnh hành vi này, chúng ta có thể thêm thuộc tính options vào một số tiện ích trường.

Exercise

Thêm tùy chọn tiện ích.

  • Thêm tùy chọn thích hợp vào trường property_type_id để ngăn việc tạo và chỉnh sửa loại thuộc tính từ chế độ xem biểu mẫu thuộc tính. Hãy xem Tài liệu tiện ích Many2one để biết thêm thông tin.

  • Thêm trường sau:

Người mẫu

Cánh đồng

Kiểu

bất động sản.property.tag

Màu sắc

số nguyên

Sau đó, thêm tùy chọn thích hợp vào trường tag_ids để thêm bộ chọn màu trên thẻ. Hãy xem FieldMany2ManyTags tài liệu về tiện ích con để biết thêm thông tin.

In Chương 5: Cuối Cùng, Một Số Giao Diện Để Khám Phá, we saw that reserved fields were used for specific behaviors. For example, the active field is used to automatically filter out inactive records. We added the state as a reserved field as well. It's now time to use it! A state field can be used in combination with an invisible attribute in the view to display buttons conditionally.

Exercise

Thêm hiển thị có điều kiện của các nút.

Sử dụng thuộc tính invisible để hiển thị các nút tiêu đề có điều kiện như được mô tả trong Mục tiêu của phần này (chú ý cách các nút 'Đã bán' và 'Hủy' thay đổi khi trạng thái được sửa đổi).

Mẹo: đừng ngần ngại tìm kiếm invisible= trong các tệp XML của SoOn để biết một số ví dụ.

Tổng quát hơn, có thể tạo một trường hình, `` chỉ đọc`` hoặc `` bắt buộc`` dựa trên giá trị của các trường khác. Lưu ý rằng hình cũng có thể được áp dụng cho các thành phần khác của chế độ xem, chẳng hạn như `` nút`` hoặc `` nhóm``.

invisible, readonlyrequired có thể có bất kỳ biểu thức Python nào làm giá trị. Biểu thức đưa ra điều kiện áp dụng thuộc tính. Ví dụ:

<form>
    <field name="description" invisible="not is_partner"/>
    <field name="is_partner" invisible="True"/>
</form>

Điều này có nghĩa là trường description không hiển thị khi is_partnerFalse. Điều quan trọng cần lưu ý là trường được sử dụng trong invisible phải hiện diện trong dạng xem. Nếu nó không hiển thị cho người dùng, chúng ta có thể sử dụng thuộc tính invisible để ẩn nó.

Exercise

Sử dụng `` vô hình``.

  • Làm cho khu vườn và hướng trở nên vô hình trong chế độ xem biểu mẫu estate.property khi không có vườn.

  • Ẩn nút 'Chấp nhận' và 'Từ chối' sau khi trạng thái ưu đãi được đặt.

  • Không cho phép thêm ưu đãi khi trạng thái thuộc tính là 'Ưu đãi được chấp nhận', 'Đã bán' hoặc 'Đã hủy'. Để làm điều này, hãy sử dụng thuộc tính readonly.

Cảnh báo

Việc sử dụng thuộc tính chỉ đọc (có điều kiện) trong dạng xem có thể hữu ích để ngăn chặn lỗi nhập dữ liệu, nhưng hãy nhớ rằng nó không cung cấp bất kỳ mức độ bảo mật nào! Phía máy chủ không có bước kiểm tra nào được thực hiện, do đó, luôn có thể ghi trên trường thông qua lệnh gọi RPC.

Danh sách

Ghi chú

Mục tiêu: ở cuối phần này, chế độ xem danh sách cơ sở lưu trú và ưu đãi phải có trang trí màu sắc. Ngoài ra, các ưu đãi và thẻ sẽ có thể chỉnh sửa trực tiếp trong danh sách và ngày có hàng sẽ bị ẩn theo mặc định.

Chế độ xem danh sách với trang trí và trường tùy chọn Danh sách có thể chỉnh sửa

Khi mô hình chỉ có một vài trường, việc chỉnh sửa bản ghi trực tiếp thông qua chế độ xem danh sách và không cần phải mở chế độ xem biểu mẫu có thể hữu ích. Trong ví dụ về bất động sản, không cần phải mở chế độ xem biểu mẫu để thêm ưu đãi hoặc tạo thẻ mới. Điều này có thể đạt được nhờ thuộc tính thể chỉnh sửa.

Exercise

Làm cho chế độ xem danh sách có thể chỉnh sửa được.

Làm cho chế độ xem danh sách estate.property.offerestate.property.tag có thể chỉnh sửa được.

Mặt khác, khi một mô hình có nhiều trường, việc thêm quá nhiều trường vào chế độ xem danh sách có thể khiến nó không rõ ràng. Một phương pháp khác là thêm các trường nhưng tùy ý ẩn chúng đi. Điều này có thể đạt được nhờ thuộc tính tùy chọn.

Exercise

Tạo một trường tùy chọn.

Đặt trường date_availability trên chế độ xem danh sách estate.property là tùy chọn và ẩn theo mặc định.

Cuối cùng, mã màu rất hữu ích để nhấn mạnh các bản ghi một cách trực quan. Ví dụ: trong mô-đun bất động sản, chúng tôi muốn hiển thị các đề nghị bị từ chối bằng màu đỏ và các đề nghị được chấp nhận bằng màu xanh lá cây. Điều này có thể đạt được nhờ thuộc tính trang trí-{$name} (xem Lĩnh vực để biết danh sách đầy đủ):

<tree decoration-success="is_partner==True">
    <field name="name"/>
    <field name="is_partner" invisible="1"/>
</tree>

Các bản ghi trong đó is_partnerTrue sẽ được hiển thị bằng màu xanh lục.

Exercise

Thêm một số đồ trang trí.

Trên chế độ xem danh sách estate.property:

  • Các tài sản nhận được lời đề nghị có màu xanh lá cây

  • Các thuộc tính được chấp nhận đề nghị có màu xanh lá cây và in đậm

  • Assets đã bán bị tắt tiếng

Trên chế độ xem danh sách estate.property.offer:

  • Các đề nghị bị từ chối có màu đỏ

  • Ưu đãi được chấp nhận có màu xanh lá cây

  • Trạng thái sẽ không còn hiển thị nữa

Lời khuyên:

  • Hãy nhớ rằng tất cả các trường được sử dụng trong thuộc tính phải ở trong chế độ xem!

  • Nếu bạn muốn kiểm tra màu của trạng thái "Đã nhận ưu đãi" và "Ưu đãi được chấp nhận", hãy thêm trường trong chế độ xem biểu mẫu và thay đổi trường theo cách thủ công (chúng tôi sẽ triển khai logic nghiệp vụ cho việc này sau).

Nút thống kê

Ghi chú

Mục tiêu: ở cuối phần này, sẽ có một nút thống kê trên chế độ xem biểu mẫu loại thuộc tính hiển thị danh sách tất cả các ưu đãi liên quan đến thuộc tính của loại nhất định khi người dùng nhấp vào.

nút thống kê

Nếu bạn đã sử dụng một số mô-đun chức năng trong SoOn, có thể bạn đã gặp phải 'nút thống kê'. Các nút này được hiển thị ở phía trên bên phải của chế độ xem biểu mẫu và cho phép truy cập nhanh vào các tài liệu được liên kết. Trong mô-đun bất động sản của chúng tôi, chúng tôi muốn có một liên kết nhanh đến các ưu đãi liên quan đến một loại bất động sản nhất định như được mô tả trong Mục tiêu của phần này.

Tại thời điểm này của hướng dẫn, chúng ta đã thấy hầu hết các khái niệm để thực hiện việc này. Tuy nhiên, không có một giải pháp duy nhất và nó vẫn có thể gây nhầm lẫn nếu bạn không biết bắt đầu từ đâu. Chúng tôi sẽ mô tả giải pháp từng bước trong bài tập. Việc tìm một số ví dụ trong cơ sở mã SoOn luôn có thể hữu ích bằng cách tìm kiếm oe_stat_button.

Bài tập sau có thể khó hơn một chút so với những bài trước vì nó giả định rằng bạn có thể tự mình tìm kiếm các ví dụ trong mã nguồn. Nếu bạn gặp khó khăn thì có lẽ có ai đó ở gần có thể giúp bạn ;-)

Bài tập giới thiệu khái niệm reference/fields/relative. Cách dễ hiểu nhất là coi nó như một trường hợp cụ thể của trường được tính toán. Định nghĩa sau đây của trường description:

...

partner_id = fields.Many2one("res.partner", string="Partner")
description = fields.Char(related="partner_id.name")

tương đương với:

...

partner_id = fields.Many2one("res.partner", string="Partner")
description = fields.Char(compute="_compute_description")

@api.depends("partner_id.name")
def _compute_description(self):
    for record in self:
        record.description = record.partner_id.name

Mỗi khi tên đối tác được thay đổi, mô tả cũng được sửa đổi.

Exercise

Thêm nút thống kê vào loại thuộc tính.

  • Thêm trường property_type_id vào estate.property.offer. Chúng ta có thể định nghĩa nó là một trường có liên quan trên property_id.property_type_id và đặt nó làm lưu trữ.

Nhờ trường này, ưu đãi sẽ được liên kết với loại tài sản khi nó được tạo. Bạn có thể thêm trường vào chế độ xem danh sách các ưu đãi để đảm bảo nó hoạt động.

  • Thêm trường offer_ids vào estate.property.type là nghịch đảo One2many của trường được xác định ở bước trước.

  • Thêm trường offer_count vào estate.property.type. Đây là một trường được tính toán để đếm số lượng ưu đãi cho một loại bất động sản nhất định (sử dụng offer_ids để làm như vậy).

Tại thời điểm này, bạn có tất cả thông tin cần thiết để biết có bao nhiêu ưu đãi được liên kết với một loại bất động sản. Khi nghi ngờ, hãy thêm trực tiếp offer_idsoffer_count vào chế độ xem. Bước tiếp theo là hiển thị danh sách khi nhấn vào nút stat.

Tại thời điểm này, nhấp vào nút thống kê sẽ hiển thị tất cả các ưu đãi. Chúng ta vẫn cần lọc ra những lời đề nghị.

  • Trên hành động estate.property.offer, hãy thêm một miền xác định property_type_id bằng với active_id (= bản ghi hiện tại, đây là một ví dụ)

Looking good? If not, don't worry, the next chapter doesn't require stat buttons ;-)