Search code examples
odooodoo-12

Why related fields use Write function


    _name = "my.table"

    building_id = fields.Many2one('building', related='floor_id.building_id', readonly=False)
    floor_id = fields.Many2one('building.floor')

A user with the read access to 'building' and 'building.floor' tables, tries to create a record in "my.table" If the user chooses building_id and floor_id together an error occurs. The error says that my user has no access to write 'building.floor' table. My question is: why a related field use the write function, what is the difference between the compute and related in this scenario?


Solution

  • Related fields are very simple computed fields. So simple they can be "implemented" with one parameter on field definition. Odoo has generic methods for those fields. For example a lot of developers don't write inverse methods for computed fields, which inverse the compute method, because the simply don't need it. But without it and without storing the computed field, Odoo sets the field readonly.

    Related fields have a generic inverse method. In your case changing building_id when there was already a floor_id chosen, Odoo will write the building_id on that floor_id.building_id, because that's how related fields work (i know that's not the best explanation).

    The user obviously has no write/update rights on builiding.floor model and that's why there will be the access error message in the end, because Odoo wants to write the new building on the floor.

    Seems to me you want to filter the floors by buildings, but you shouldn't use a related field for that. Just put a domain on floor_id which filters by the chosen building_id:

    floor_id = fields.Many2one('building.floor', domain="[('building_id', '=?', building_id)]")
    

    You could also use domain operator =, but =? will show all floors when no building was set yet.