第11章:Sprinklesの追加

当社の不動産モジュールは、ビジネスの観点から理にかなっています。 :doc:`具体的なビュー<06_basicviews>`を作成し、いくつかの :doc:`アクションボタン<09_actions>`と :doc:`constraints <10_constraints>`を追加しました。 しかし、私たちのユーザーインターフェイスはまだ少しラフです。 リストビューにいくつかの色を追加し、フィールドとボタンを条件付きで消去したいと思います。 例えば、 この時点で状態を変更することができなくなったため、プロパティが売却またはキャンセルされたときに、「販売」および「キャンセル」ボタンは消えるはずです。

この章では、ビューでできることのごく一部を説明しています。より完全な概要を知りたい場合は、躊躇なくリファレンスドキュメントをお読みください。

参照: この章に関連するドキュメントは View recordsアーキテクチャを表示 にあります。

インライン ビュー

注釈

目標: このセクションの最後には、物件情報の特定のリストが物件タイプビューに追加されています。

インラインリスト表示

不動産モジュールでは、ある物件に対するオファーのリストを追加しました。単純にフィールド offer_ids を次のように追加しただけです。

<field name="offer_ids"/>

このフィールドは、 estate.property.offer の特定のビューを使用します。場合によっては、フォームビューのコンテキストでのみ使用される特定のリストビューを定義したいことがあります。例えば、ある物件タイプにリンクされた物件のリストを表示したいとします。しかし、わかりやすくするために、名前(name)、想定価格(expected price)、状態(state)の3つのフィールドだけを表示したいとします。

これを実現するには、 インライン リストビューを定義します。インラインリストビューは、フォームビューの中に直接定義されます。例えば、次のようになります。

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">
        <list>
            <field name="field_1"/>
            <field name="field_2"/>
        </list>
    </field>
</form>

test_model のフォームビューでは、field_1field_2 フィールドを持つ、 test_model_line の特定のリストビューを定義します。

例は こちら です。

Exercise

インラインリストビューを追加してみましょう。

  • One2many フィールドとして property_idsestate.property.type モデルに追加します。

  • このセクションの 目標 に示されているように、estate.property.type フォームビューにフィールドを追加します。

ウィジェット

参考: このトピックに関連するドキュメントは、 フィールド にあります。

注釈

目標: このセクションの最後には、特定のウィジェットを使用して物件情報の状態が表示されています。

ステータスバーウィジェット

4つの状態が表示されます: 新着(New)、オファー受理(Offer Received)、オファー承認済(Offer Accepted)、売却済(Sold)

モデルにフィールドを追加する際に、ユーザーインターフェースでの表示方法を気にする必要は(ほとんど) ありませんでした。例えば、 Date フィールドには日付ピッカーが提供され、 One2many フィールドは自動的にリストとして表示されます。Odooはフィールドタイプに応じて、適切な widget (ウィジェット) を選択します。

しかし、場合によっては、フィールドに対して特定の表現が必要になることがありますが、 widget 属性のおかげでそれが可能です。 tag_ids フィールドに widget="many2many_tags" 属性を使用したときに、すでにこの属性を使用しました。この属性を使用しなかった場合、フィールドはリストとして表示されていました。

各フィールドタイプには、表示を微調整するために使用できるウィジェットのセットがあります。ウィジェットの中には追加のオプションを取るものもあります。詳細なリストは、 フィールド を参照してください。

Exercise

ステータス・バー ウィジェットを使ってみましょう。

statusbar ウィジェットを使って、このセクションの 目標 に示されているように estate.propertystate を表示します。

ヒント: 簡単な例は こちら です。

警告

1つのビューに複数の同じフィールド

リストやフォームビューにフィールドを 一度 だけ追加します。複数回の追加はサポートされていません。

リストの並び順

参考: このトピックに関連する文書は モデル にあります。

注釈

目標: このセクションの最後では、すべてのリストがデフォルトである決まった並び順で表示されるようにします。物件タイプは、手動で順序付けすることができます。

これまでの演習では、いくつかのリストビューを作成しました。しかし、レコードがどのような並び順でデフォルト表示されなければならないかを指定したことはありませんでした。これは多くのビジネスケースで非常に重要なことです。例えば、不動産モジュールでは、最高額のオファーをリストの一番上に表示したいと思います。

モデル

Odooには、デフォルトの並び順を設定する方法がいくつかあります。最も一般的な方法は、モデルに _order 属性を直接定義することです。この方法では、検索されたレコードは、プログラムでレコードを検索する場合も含めて、すべてのビューで一貫したある決められた並び順になります。デフォルトでは並び順は指定されていませんので、レコードはPostgreSQLに依存した特に定めのない並び順で検索されます。

_order 属性には、並び替えに使用されるフィールドのリストを含む文字列を指定します。これは、SQLの order_by 句に変換されます。例えば、次のようになります。

from odoo import fields, models

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

    description = fields.Char()

レコードは id の降順で並べられています。これは、最高値が先に来ることを意味しています。

Exercise

モデルに並び順を追加してみましょう。

つぎのような順序を、対応するモデルに定義してください。

モデル

並び順

estate.property

ID の降順

estate.property.offer

価格(price)の降順

estate.property.tag

名前(name)

estate.property.type

名前(name)

ビュー

並び順の指定はモデルレベルで可能です。これには、レコードのリストが検索される際に一貫した順序が得られるという利点があります。しかし、 default_order 属性() のおかげで、ビューで直接特定の並び順を定義することも可能です。

手動操作

モデルとビューの並び順は、レコードをソートする際に柔軟に対応できますが、手動操作による並び順もカバーする必要があります。ユーザーは、ビジネスロジックに応じてレコードをソートしたいと思うかもしれません。例えば、不動産モジュールでは、物件タイプを手動でソートしたいとします。最も使用されているタイプがリストの一番上に表示されるのは確かに便利です。不動産会社が主に住宅を販売している場合、 アパート (Apartment)の前に 住宅 (House)が表示されている方が便利です。

そのためには、 sequence フィールドを handle ウィジェットと組み合わせて使用します。当然ながら、 sequence フィールドは _order 属性の最初のフィールドでなければなりません。

Exercise

手動操作の並び順付けを追加しましょう。

  • 次のフィールドを追加します。

モデル

フィールド

estate.property.type

シーケンス

整数

  • 正しいウィジェットを使って estate.property.type リストビューにシーケンス(sequence)を追加します。

ヒント: modelview の例があります。

属性とオプション

ビューの外観を微調整するために利用できるすべての機能を詳細に説明することは不可能でしょう。そのため、ここでは最も一般的なものを紹介します。

フォーム

注釈

目標: このセクションの最後には、物件情報フォームビューには次のものが備わっています。

  • ボタンとフィールドの条件付き表示

  • タグの色

スプリンクルのフォームビュー

不動産モジュールにおいて、いくつかのフィールドの動作を変更したいと考えています。例えば、フォームビューから物件タイプの作成や編集はできないようにしたいと思います。その代わり、物件タイプは適切なメニューで処理されるようにします。また、タグに色をつけたいと思います。これらの動作のカスタマイズを追加するために、いくつかのフィールドウィジェットに options 属性を追加します。

Exercise

ウィジェットのオプションを追加してみましょう。

  • property_type_id フィールドに適切なオプションを追加して、物件情報フォームビューから物件タイプの作成と編集ができないようにします。詳細は、 Many2one ウィジェットのドキュメント を参照してください。

  • 次のフィールドを追加します。

モデル

フィールド

estate.property.tag

整数

次に、タグにカラーピッカーを追加するために、 tag_ids フィールドに適切なオプションを追加します。詳細は :ref:`FieldMany2ManyTagsウィジェットのドキュメント <reference/js/widgets>`を参照してください。

第5章:最後に、いくつかのUIで遊べるもの では、予約フィールドが特定の動作に使用されていることがわかりました。 たとえば、非アクティブなレコードを自動的にフィルタリングするために active フィールドが使用されます。 state も予約済みフィールドに追加しました。 それを使用する時が来ました! state フィールドと invisible 属性を組み合わせて使用することで、ボタンを条件付きで表示できます。

Exercise

ボタンの条件付き表示を追加してみましょう。

invisible 属性を使用して、セクションの**ゴール** に示されているようにヘッダーボタンを条件付きで表示します(状態が変更されると'Sold'と'Cancel'ボタンがどのように変化するか注意してください)。

ヒント: Odoo XML ファイル内の invisible= をいくつかの例で検索することを躊躇しないでください。

より一般的には、他のフィールドの値に基づいて、フィールド invisiblereadonly 、または required を作成することができます。 invisible は、buttongroup などのビューの他の要素にも適用できます。

invisiblereadonly、および `required`は任意のPython式を値として持つことができます。式は、プロパティが適用される条件を与えます。例えば:

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

これは、 is_partnerFalse の場合、description フィールドは見えないことを意味します。 invisible で使用されているフィールドは、ビューに必ず存在することに注意してください。 ユーザーに表示しない場合は、invisible 属性を使用して非表示にできます。

Exercise

invisible を使用します。

  • 庭がないときに estate.property フォームのビューで、庭の面積と方角を非表示にします。

  • offer(オファー)の状態に設定されると、 'Accept' (承諾)と 'Refuse' (拒否)のボタンが非表示しなるようにします。

  • プロパティの状態が「Offer Accepted」、「Sold」、「Cancelled」の場合、オファーを追加することを許可しないでください。これを行うには、readonly 属性を使用します。

警告

ビューで(条件付き) readonly 属性を使用することは、データ入力のエラーを防ぐのに便利ですが、これはいかなるレベルのセキュリティも提供しないことに留意してください。サーバーサイドでのチェックは行われませんので、RPCコールを介してフィールドに書き込むことは常に可能です。

一覧表示

注釈

目標: このセクションの最後には、物件情報とオファーのリストビューにカラーの装飾が施されます。さらに、オファーとタグはリスト内で直接編集可能になり、入居可能日はデフォルトで非表示になります。

装飾と任意のフィールドを持つリストビュー 編集可能なリスト

モデルにいくつかのフィールドしかない場合、フォームビューを開く必要もなく、リストビューで直接レコードを編集できると便利です。不動産の例では、オファーの追加や新しいタグの作成のために、フォームビューを開く必要がありません。これは、 editable 属性のおかげです。

Exercise

リストビューを編集可能にしてみましょう。

estate.property.offerestate.property.tag リストビューを編集可能にします。

一方、モデルに多くのフィールドがある場合、リストビューに多くのフィールドを追加したくて、不明瞭にしてしまうことがあります。別の方法としては、フィールドを追加しても、オプションで非表示にすることができます。これは、 optional 属性のおかげで実現できます。

Exercise

フィールドを任意にしてみましょう。

estate.property リストビューのフィールド date_availability を任意にして、デフォルトで非表示にします。

最後に、カラーコードはレコードを視覚的に強調するのに便利です。例えば、不動産モジュールでは、否認されたオファーを赤で、承認されたオファーを緑で表示したいとします。これは decoration-{$name} 属性のおかげで実現できます(完全なリストについては フィールド を参照してください)。

<list decoration-success="is_partner==True">
    <field name="name"/>
</list>

is_partner がTrueのレコードは、緑色で表示されます。

Exercise

装飾を追加してみましょう。

estate.property のリストビューでは、次のようにします。

  • オファーを受け取った物件情報は緑色です

  • オファーが承認された物件情報は緑で太字です

  • 売却済みの物件情報はミュートされます。

estate.property.offer リストビューでは、次のようにします。

  • 否認されたオファーは赤です

  • 承認されたオファーは緑です。

  • 状態を非表示にします。

ヒント:

  • 属性で使用される すべての フィールドは、ビュー内になければならないことに注意してください。

  • "Offer Received" と "Offer Accepted" の状態の色をテストしたい場合は、フォームビューにフィールドを追加して、手動で変更してください(このためのビジネスロジックは後ほど実装します)。

統計ボタン

注釈

目標: このセクションの最後には、物件タイプのフォームビューに統計ボタンがあり、クリックすると指定されたタイプの物件情報に関連するすべてのオファーのリストが表示されるようになります。

統計ボタン

Odooでいくつかの機能モジュールを使用したことがある方は、おそらく 統計ボタン に遭遇したことがあると思います。このボタンは、フォームビューの右上に表示され、リンクされたドキュメントに素早くアクセスすることができます。不動産モジュールでは、このセクションの 目標 に示されているように、特定の物件タイプに関連するオファーへのクイックリンクを用意したいと思います。

このチュートリアルの現時点で、これを実現するためのコンセプトのほとんどを見てきました。しかし、唯一の解決策があるわけではなく、どこから始めればいいのかわからないと混乱してしまうかもしれません。練習問題では、ステップバイステップの解決策を説明します。Odooのコードベースで oe_stat_button を探して例を見つけることは常に有用です。

次の練習問題は、あなたが自分でソースコードの中から例題を探せることを前提としているので、これまでの練習問題よりも少し難しいかもしれません。困ったときには、近くに助けてくれる人がいるかもしれません。 ;-)

この演習では、 関連フィールド の概念を紹介します。これを理解する最も簡単な方法は、計算フィールドのあるケースで考えることです。次の description フィールドの定義を見てみましょう。

...

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

これは次と同等です。

...

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

パートナー(partner)の名前(name)が変更されるたびに、説明(description)も変更されます。

Exercise

物件タイプに統計ボタンを追加してみましょう。

  • estate.property.offer にフィールド property_type_id を追加します。 property_id.property_type_id の関連フィールドとして定義し、それを stored として設定できます。

このフィールドのおかげで、オファーが作成されたときに物件タイプにリンクされます。オファーのリストビューにこのフィールドを追加して、動作を確認します。

  • estate.property.type にフィールド offer_ids を追加します。これは、これまでのステップで定義したフィールドを逆参照するOne2manyフィールドです。

  • estate.property.type にフィールド offer_count を追加します。これは、指定された物件タイプに対するオファーの数をカウントする計算フィールドです(これを行うのに offer_ids を使用します)。

この時点で、ある物件タイプに何件のオファーがリンクされているかを知るために必要な情報はすべて揃っています。疑問がある場合は、 offer_idsoffer_count を直接ビューに追加してください。次のステップは、統計ボタンをクリックしたときにリストを表示するようにします。

  • estate.property.typeestate.property.offer アクションを指す統計ボタンを作成します。 これは``type="action"`` 属性を使用する必要があることを意味します (リフレッシュが必要な場合は、 第9章: アクションの準備はできましたか? の末尾に戻ります)。

この時点で、統計ボタンをクリックすると、すべてのオファーが表示されます。さらにオファーをフィルタリングする必要があります。

  • estate.property.offer アクションに、 property_type_idactive_id (=現在のレコード これがその例) と等しいと定義したドメインを追加します。

良いですか?心配しないでください、 :doc:`次の章<12_継承>`は統計ボタンを必要としません ;-)