How to create non-table column for a Form

Hi,

I have below class:

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:

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

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.

1 Like

Hi @nicoe

I have download the entire trytond 7.4 and checked the use of context_model there. And I got this code block:

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:

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:

<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 :laughing:

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 :smiling_face_with_tear:
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

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 for the aged balance context and modules/account/account.py · 2eade80a07c5b6a4169aa1c5aa7453826ab8444f · Tryton / Tryton · GitLab 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

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

2 Likes

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:

1 Like