DEV Community

Khaled Said
Khaled Said

Posted on • Edited on

9 1

Dynamic Selection List for Selection Fields in Odoo ft

Dynamic list can be approached by 3 patterns when defining selection fields in Odoo. These patterns are old however some colleagues may find them weird. These patterns are helpful instead of hard-coding the definition of each related fields.Selection.

The First Pattern:
You could define a global variable then to import in your class file definition. Such as the following global variable TYPE_TAX_USE:
addons/account/models/account_tax.py

# base class with the first definition
TYPE_TAX_USE = [
    ('sale', 'Sales'),
    ('purchase', 'Purchases'),
    ('none', 'None'),
]


class AccountTax(models.Model):
    _name = 'account.tax'

    type_tax_use = fields.Selection(TYPE_TAX_USE, string='Tax Type', required=True, default='sale')
Enter fullscreen mode Exit fullscreen mode

Now, You could import the variable as following:
addons/account/models/chart_template.py

from odoo.addons.account.models.account_tax import TYPE_TAX_USE


class AccountTaxTemplate(models.Model):
    _name = 'account.tax.template'

    type_tax_use = fields.Selection(TYPE_TAX_USE, string='Tax Type', required=True, default='sale',)
Enter fullscreen mode Exit fullscreen mode

The Second Pattern:
if the model have a relation with your model. You could use the related attribute in the field definition. internal_type field is an example in the following snippet:
addons/account/models/account_account.py

class AccountAccount(models.Model):
    _name = 'account.account'

    user_type_id = fields.Many2one('account.account.type', string='Type', required=True,)
    internal_type = fields.Selection(related='user_type_id.type', string='Internal Type' store=True, readonly=True)
Enter fullscreen mode Exit fullscreen mode

The Third Pattern:
you could use a function to return such list. This function should also be outside the class definition for auto invocation.
odoo/addons/base/models/res_partner.py

import pytz

_tzs = [(tz, tz) for tz in sorted(pytz.all_timezones, key=lambda tz: tz if not tz.startswith('Etc/') else '_')]
def _tz_get(self):
    return _tzs


class Partner(models.Model):
_name = 'res.partner'

    tz = fields.Selection(_tz_get, string='Timezone', default=lambda self: self._context.get('tz'),)
Enter fullscreen mode Exit fullscreen mode

Another example could be as following:

def _get_purchase_order_states(self):
    return self.env['purchase.order']._fields['state'].selection

class PurchaseReport(models.Model):
    _name = 'purchase.report'

    state = fields.Selection(_get_purchase_order_states, string='Order States')

Enter fullscreen mode Exit fullscreen mode

Speedy emails, satisfied customers

Postmark Image

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free →

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay