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 ghi và Xem 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:

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_1
và field_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ìnhestate.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ể:

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 |
---|---|
|
ID giảm dần |
|
Giá giảm dần |
|
Tên |
|
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ử lý
. Rõ ràng trường sequence
phải là trường đầu tiên trong thuộc tính _order
.
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ẻ

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 |
---|---|---|
|
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 vô 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 vô 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
, readonly
và required
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_partner
là False
. Đ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.


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 có 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.offer
và estate.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_partner
là True
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).
Tìm kiếm¶
Tham khảo: tài liệu liên quan đến phần này có thể được tìm thấy trong Tìm kiếm và Tìm kiếm mặc định.
Ghi chú
Mục tiêu: ở cuối phần này, các thuộc tính có sẵn sẽ được lọc theo mặc định và tìm kiếm trên khu vực sinh sống sẽ trả về kết quả có diện tích lớn hơn số đã cho.

Cuối cùng nhưng không kém phần quan trọng, có một số chỉnh sửa mà chúng tôi muốn áp dụng khi tìm kiếm. Trước hết, chúng tôi muốn áp dụng bộ lọc 'Có sẵn' theo mặc định khi chúng tôi truy cập các thuộc tính. Để thực hiện điều này, chúng ta cần sử dụng ngữ cảnh hành động search_default_{$name}
, trong đó {$name}
là tên bộ lọc. Điều này có nghĩa là chúng tôi có thể xác định (các) bộ lọc nào sẽ được kích hoạt theo mặc định ở cấp hành động.
Dưới đây là ví dụ về hành động với bộ lọc tương ứng.
Exercise
Thêm bộ lọc mặc định.
Đặt bộ lọc 'Có sẵn' được chọn theo mặc định trong hành động estate.property
.
Một cải tiến hữu ích khác trong mô-đun của chúng tôi là khả năng tìm kiếm hiệu quả theo khu vực sinh sống. Trong thực tế, người dùng sẽ muốn tìm kiếm các thuộc tính của “ít nhất” khu vực nhất định. Sẽ là không thực tế nếu mong đợi người dùng muốn tìm một bất động sản có đúng khu vực sinh sống. Luôn có thể thực hiện tìm kiếm tùy chỉnh, nhưng điều đó thật bất tiện.
Các phần tử <field>
của chế độ xem tìm kiếm có thể có filter_domain
ghi đè miền được tạo để tìm kiếm trên trường nhất định. Trong miền nhất định, self
đại diện cho giá trị do người dùng nhập. Trong ví dụ bên dưới, nó được sử dụng để tìm kiếm trên cả hai trường name
và description
.
<search string="Test">
<field name="description" string="Name and description"
filter_domain="['|', ('name', 'ilike', self), ('description', 'ilike', self)]"/>
</search>
Exercise
Thay đổi tìm kiếm khu vực sinh sống.
Thêm filter_domain
vào khu vực sinh sống để bao gồm các thuộc tính có diện tích bằng hoặc lớn hơn giá trị nhất định.