In this article you will learn how to return domain on onchange of many2one field in Odoo. In other words we are going to create a dependent drop down (many2one) field in Odoo.
Return Domain on Onchange of Many2One Field
Read More: How to Create Model and Fields in Odoo
Read More: How to Create Model and Fields in Odoo13
For example I have two many2one fields (campus_id and department_id), and we want to change the department on the basis of campus field. To achieve this we will use @api.onchange function provided by Odoo and return domain filter.
Read More: How to Add domain on Many2many Field
campus_id = fields.Many2one('model.campus', string="Campus Name")department_id = fields.Many2one('model.department', string="Department Name")
Code Description
In line no 1 we use @api.onchange decorator for campus_id. It means whenever campus changes or select a campus from many2one filed do the following line of code (3,4,5). In line no 3 we declare a dict named res. In line no 4 we use domain to change the department field.
res['domain'] = {'department_id':[('campus_id', '=', self.campus_id.id)]}
| |
| |
(field name which is to changed) (field name which is intended to change)
18 Comments
Please describe more in depth for better understanding.
ReplyDeleteTell me the problem you are facing?
DeleteCould you please explain how this syntax works? The post explains only 2 of the elements:
Delete- department_id
- campus_id
What exactly does 'domain' mean? 'self'? 'self.campus_id.id?
domain is the keyword provided by odoo (by using domain you can filters records), slef is the current object like "your.model(1,2,3)" here self.campus_id means from "your.model(1)" you want to get campus_id
DeleteIs it possible to create a record of another model (a mail.activity) associated to the record that has changed?
ReplyDeleteThis is my code:
@api.onchange('stage_id')
def _onchange_stage_id(self):
values = self._onchange_stage_id_values(self.stage_id.id)
event_user_id = self.user_id
self.update(values)
if self.stage_id.id == 3:
self = self.env['event_mgmt.event_mgmt'].browse(self._origin.id)
activity = self.env['mail.activity']
activity_ins = activity.create(
{'res_id': self.id,
'res_model_id': 170,
'res_model':'event_mgmt.event_mgmt',
'activity_type_id':2,
'summary': 'Follow Up',
'note':'Han pasado 5 dÃas desde el paso a propuesta. Realizar seguimiento a la propuesta enviada.',
'date_deadline': date.today() + timedelta(days=5),
'activity_category':'default',
'previous_activity_type_id': False,
'recommended_activity_type_id': False,
'user_id': self.user_id.id
})
The onchange applies to a crm.lead record and I would like to create an activity (as a reminder) when the stage changes.
Any help would be very appreciated
under your onchange methode use below code snippet to create records for another model:
Deletevalues = {
'key1':value1,
'key2':value2,
'key3':value3
}
create_another_model_records = self.env['another.model'].create(values)
does this work on Odoo 10?
ReplyDeletethe concept is same
Deleteit's not working in Odoo 12. Do we have to create on_change method in Views?
ReplyDeleteDo we have to create On_method in Views in Odoo
ReplyDeleteHello,
ReplyDeleteI want only administrators in the field of many2one how to can do.
Add this group to your many2one field: groups="base.group_erp_manager"
DeleteHi,
ReplyDeleteDoes this works the same if my onchange function is in Wizard?
yes you can use above method in any of your model like model.Model or wizard (models.TransientModel)
Deleteboardmanagement_id = fields.Many2one('audit.boardmanagement', string='Board/Management', ondelete='set null')
ReplyDeletegroupdivision_id = fields.Many2one('audit.groupdivision', string='Group/Division', ondelete='set null')
@api.onchange('boardmanagement_id')
def _boardmanagement_onchange(self):
res = {'domain': {'groupdivision_id': [('boardmanagement_id', '=', self.boardmanagement_id.id)]}}
return res
Error: ValueError: Invalid field 'boardmanagement_id' in leaf "<osv.ExtendedLeaf: ('boardmanagement_id', '=', 1) on audit_groupdivision (ctx: )>"
the boardmanagment_id does not exist
Deletefacility_ids = fields.Many2many('hotel.facility', string="Facility")
ReplyDeleteroom_id = fields.Many2one('hotel.room', string="Room Number")
i want to set the domain of room_id when multiple values of facility ids are selected.
does facility_ids has room_id, if yes than you can apply domain on onchange of facility_ids. just use above code like this
Delete@api.multi
@api.onchange('facility_ids')
def set_room_domain(self):
facility_obj = self.env['hotel.facility'].search([('some_id', '=', id_goes_here))])
res = {}
if facility_obj:
room_obj = self.env['hotel.room'].sudo().search([('id', '=', facility_obj.room_id.id)])
res['domain'] = {'room_id': [('id', 'in', room_obj.ids)]}
return res