# How to create non-table column for a Form

**URL:** <https://discuss.tryton.org/t/how-to-create-non-table-column-for-a-form/8593>\
**Category:** Developer\
**Created:** [May 14, 2025, 3:43pm UTC](https://discuss.tryton.org/t/how-to-create-non-table-column-for-a-form/8593 "2025-05-14T15:43:23Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![bromoapp](https://discuss-cdn.tryton.org/letter_avatar_proxy/v4/letter/b/71c47a/32.png) [@bromoapp](https://discuss.tryton.org/u/bromoapp)\
**Post date:** [May 14, 2025, 3:43pm UTC](https://discuss.tryton.org/t/how-to-create-non-table-column-for-a-form/8593/1 "2025-05-14T15:43:24Z")

</div>

Hi,

I have below class:

```auto
class ProjectMasterList(ModelSQL, ModelView):
    'Project Master List'
    __name__ = 'afx.project.master.list'

    # Table column
    list_name = fields.Char('List Name', required=True, readonly=True)

    # Non Table column
    duration = fields.Selection('_get_durations', 'Duration', sort=False)
    resource_name = fields.Selection('_get_resource_names', 'Resource Name')
    client_name = fields.Selection('_get_client_names', 'Client Name')
    team = fields.Selection('_get_teams', 'Team', sort=False)
    proj_name = fields.Selection('_get_proj_names', 'Project Name', sort=False)
    proj_status = fields.Selection([], 'Project Status', sort=False)
    completion = fields.Selection([], 'Completion', sort=False)
    start_date = fields.Date('Start Date')
    end_date = fields.Date('End Date')
    pic = fields.Selection('_get_resource_names', 'PIC')
    duration = fields.Selection([], 'Duration', sort=False)

    projects = fields.One2Many('afx.project.master.list.record', 'tracklist', 'Projects', 
        readonly=True, required=False
    )

```

With Frontend like below:

 ![mastersheet_dash06](https://discuss-cdn.tryton.org/uploads/default/original/2X/6/67ad6f4b5efdbaa4d457e6c503e224b7e124bd6e.jpeg)

My original idea is that only “List Name” would be a table field while the rest are non-table fields and will just works as a filter to filter the table (Projects) below the form.

How to make this happen?

Regards  
Bromo

---

<div class="post-metadata">

**Author:** ![nicoe](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/nicoe/32/2880_2.png) [@nicoe](https://discuss.tryton.org/u/nicoe)\
**Post date:** [May 14, 2025, 4:12pm UTC](https://discuss.tryton.org/t/how-to-create-non-table-column-for-a-form/8593/2 "2025-05-14T16:12:32Z")

</div>

You probably should use a `context_model` on the `act_window` showing the projects instead of using a specific model with a computed fields for the projects.

There are example of use of `context_model` in the `account` module.

---

<div class="post-metadata">

**Author:** ![bromoapp](https://discuss-cdn.tryton.org/letter_avatar_proxy/v4/letter/b/71c47a/32.png) [@bromoapp](https://discuss.tryton.org/u/bromoapp)\
**Post date:** [May 15, 2025, 1:47am UTC](https://discuss.tryton.org/t/how-to-create-non-table-column-for-a-form/8593/3 "2025-05-15T01:47:45Z")

</div>

Hi @nicoe

I have download the entire trytond 7.4 and checked the use of **context\_model** there. And I got this code block:

```auto
class OpenType(Wizard):
    'Open Type'
    __name__ = 'account.account.open_type'
    start = StateTransition()
    account = StateAction('account.act_account_balance_sheet')
    ledger_account = StateAction('account.act_account_general_ledger')

    def transition_start(self):
        context_model = Transaction().context.get('context_model')
        if context_model == 'account.balance_sheet.comparison.context':
            return 'account'
        elif context_model == 'account.income_statement.context':
            return 'ledger_account'
        return 'end'

```

So I traced it and got this class:

```auto
class IncomeStatementContext(ModelView):
    'Income Statement Context'
    __name__ = 'account.income_statement.context'
    fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscal Year',
        required=True,
        domain=[
            ('company', '=', Eval('company', -1)),
            ])
    start_period = fields.Many2One('account.period', 'Start Period',
        domain=[
            ('fiscalyear', '=', Eval('fiscalyear', -1)),
            ('start_date', '<=', (Eval('end_period'), 'start_date'))
            ],
        states={
            'invisible': Eval('from_date', False) | Eval('to_date', False),
            })
#------------- many more codes --------------------

```

And that class is also declared in xml as below:

```auto
<record model="ir.action.act_window" id="act_account_income_statement_tree">
            <field name="name">Income Statement</field>
            <field name="res_model">account.account.type</field>
            <field name="context_model">account.income_statement.context</field>
            <field name="context_domain"
                eval="[('company', '=', Eval('company', -1))]"
                pyson="1"/>
            <field name="domain"
                eval="[('statement', '=', 'income'), ['OR', ('parent', '=', None), ('parent.statement', '!=', 'income'), ('parent.statement', '=', None)]]"
                pyson="1"/>
        </record>

```

Based on these findings, I found that the class model is mapped to a table too, even thou that class is inherit only **ModelView**.  
So to be honest, I am a bit in confused here.. maybe because this is my first time using python for coding 😆

Ok let me try to digest here:

1. I create a ModelView only class, let say I named it **Child**
2. Declare it in module’s xml
3. Instantiate that **Child** class from a **Parent** class using **child\_field = Child**
4. Renders that Parent class, and the **child\_field** will show a form?

I hope my understanding correct 🥲  
But to be honest.. I still cannot find a concrete sample using the **account** module that can describe the How To. Has anybody knows a simpler sample?

Regards  
Bromo

---

<div class="post-metadata">

**Author:** ![edbo](https://discuss-cdn.tryton.org/letter_avatar_proxy/v4/letter/e/f14d63/32.png) [@edbo](https://discuss.tryton.org/u/edbo)\
**Post date:** [May 15, 2025, 9:31am UTC](https://discuss.tryton.org/t/how-to-create-non-table-column-for-a-form/8593/4 "2025-05-15T09:31:16Z")

</div>

The context model and the ‘main’ model are only connected through the XML. The context model does not have a database table but is only a view, hence it only subclasses the `ModelView`. You can see the context model / view as a filter system to reduce the amount of records or get a specific set of records.

Take a look at [modules/account/account.py · 2eade80a07c5b6a4169aa1c5aa7453826ab8444f · Tryton / Tryton · GitLab](https://foss.heptapod.net/tryton/tryton/-/blob/2eade80a07c5b6a4169aa1c5aa7453826ab8444f/modules/account/account.py?page=3#L2833) for the aged balance context and [modules/account/account.py · 2eade80a07c5b6a4169aa1c5aa7453826ab8444f · Tryton / Tryton · GitLab](https://foss.heptapod.net/tryton/tryton/-/blob/2eade80a07c5b6a4169aa1c5aa7453826ab8444f/modules/account/account.py?page=3#L2908) for the ‘main’ aged balance model. As you can see, the context model has the same fields so when you change those fields, and click reload, the values of those fields are send to Tryton server and used in the ‘main’ aged balance model to build the query.

The context model is ‘connected’ to the the main model using XML, see [modules/account/account.xml · branch/default · Tryton / Tryton · GitLab](https://foss.heptapod.net/tryton/tryton/-/blob/branch/default/modules/account/account.xml?ref_type=heads#L899)

This is how I understand how this works, maybe I’m wrong.

---

<div class="post-metadata">

**Author:** ![nicoe](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/nicoe/32/2880_2.png) [@nicoe](https://discuss.tryton.org/u/nicoe)\
**Post date:** [May 15, 2025, 12:30pm UTC](https://discuss.tryton.org/t/how-to-create-non-table-column-for-a-form/8593/5 "2025-05-15T12:30:25Z")

</div>

> [@bromoapp](#):
>
> Ok let me try to digest here:
> 
> 1. I create a ModelView only class, let say I named it **Child**
> 2. Declare it in module’s xml
> 3. Instantiate that **Child** class from a **Parent** class using **child\_field = Child**
> 4. Renders that Parent class, and the **child\_field** will show a form?
> 
> I hope my understanding correct 🥲

Nope. The first two steps are kind of OK.

The goal of a context model (let’s call it `A`) is to display a form above the tree view of another model (let’s call it `B`). This form will set some values in the context that can be used when implementing `search` in `B`.

1. You create `B` which inherits from `ModelView` (presenting / viewing data) and `ModelSQL` (storing in SQL the data)
2. You create `A` which inherits from `ModelView` (it might inherits from something else but it’s not relevent when `A` is used as a context model).
3. In the definition of the `act_window` of `B`, you add a `context_model` field pointing to `A`.
4. You override `search` of B to make use of the information found in the context.

Example:

- [A context model on the general ledger](https://demo7.6.tryton.org/#demo7.6/model/account.general_ledger.account;context=%7B%22context_model%22%3A%22account.general_ledger.account.context%22%2C%22company%22%3A1%2C%22end_period%22%3Anull%2C%22fiscalyear%22%3A2%2C%22from_date%22%3Anull%2C%22journal%22%3Anull%2C%22posted%22%3Afalse%2C%22start_period%22%3Anull%2C%22to_date%22%3Anull%7D&context_model=account.general_ledger.account.context&search_value=%5B%5B%22line_count%22%2C%22!%3D%22%2C0%5D%5D&views=%5B210%5D)
- [An exemple of using the context to compute function fields](https://foss.heptapod.net/tryton/tryton/-/blob/2eade80a07c5b6a4169aa1c5aa7453826ab8444f/modules/account/account.py?page=3#L2057) … but the context could be used for other computations (such as in `search`).
