Dynamic Selection List for Selection Fields in Odoo ft
Khaled Said
Posted on February 5, 2022
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')
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',)
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)
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'),)
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')
Posted on February 5, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.