using _inherit and _name for a class is not modular
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Odoo Server (MOVED TO GITHUB) |
Confirmed
|
Low
|
OpenERP Publisher's Warranty Team |
Bug Description
If you define a class that use _inherit and _name, to make a copy of the parent class, you expect that any modification made by a tier module is applied to both the parent and the copy classes. But it's not the case and here are the steps to help you to figure it out:
1°) My aim is to use a copy of the stock.picking class for incoming shipments, it will allow me to simplify the code a lot (especially in the views definition). So i defined a class stock.picking.in as follow (stock/stock.py):
class stock_picking_
_inherit= 'stock.picking'
_name=
_table=
...
2°) in purchase module, i changed the one2many field on the purchase order that referred to the stock_picking table. What i need to do is to reference the class stock.picking.in, instead of the stock.picking. So i defined it as follow (purchase/
3°) the purchase module already include some code to add the field purchase_id on the stock.picking class and table (purchase/
37 class stock_picking(
38 _inherit = 'stock.picking'
39 _columns = {
40 'purchase_id': fields.
41 ondelete='set null', select=True),
42 }
So i thought it would be ok like this... But, no it isn't. At the purchase module installation a traceback is telling me that the field purchase_id doesn't exists on the stock.picking.in model. The addition of it on stock.picking didn't propagate to my class.
This is really problematic because it means that using _inherit and _name on the same class is not modular.
*Note that, in the meanwhile this bug is solved (if it will be) i this used a workaround: i just copied the add of the purchase_id field on my new stock.picking.in class too, in this way (purchase/
129 # Redefinition of the new field in order to update the model stock.picking.in in the orm
132 class stock_picking_
133 _inherit = 'stock.picking.in'
134 _columns = {
135 'purchase_id': fields.
136 ondelete='set null', select=True),
137 }
So yeah, it works but it's not convenient. If we want to use more and more this feature we should improve its modularity. Please be kind and remove this hack[*] whenever the framework support this feature.
Thanks,
Quentin
[*]: the same applies for the sale module, of course. Lines to remove when it's fixed are in sale/stock.py
189 # Redefinition of the new field in order to update the model stock.picking.out in the orm
192 class stock_picking_
193 _inherit = 'stock.picking.out'
194 _columns = {
195 'sale_id': fields.
196 ondelete='set null', select=True),
197 }
Related branches
- Vo Minh Thu (community): Needs Fixing
- Raphael Collet (OpenERP) (community): Needs Fixing
-
Diff: 1565 lines (+602/-362)31 files modifieddoc/changelog.rst (+5/-0)
openerp/addons/__init__.py (+4/-12)
openerp/addons/base/__init__.py (+1/-0)
openerp/addons/base/ir/ir_actions.py (+2/-1)
openerp/addons/base/ir/ir_attachment.py (+2/-1)
openerp/addons/base/ir/ir_filters.py (+2/-1)
openerp/addons/base/ir/ir_model.py (+9/-4)
openerp/addons/base/ir/ir_translation.py (+3/-1)
openerp/addons/base/ir/ir_ui_view.py (+6/-3)
openerp/addons/base/ir/ir_values.py (+2/-1)
openerp/addons/base/ir/workflow/workflow.py (+4/-2)
openerp/addons/base/models.py (+19/-0)
openerp/addons/base/module/module.py (+6/-6)
openerp/conf/deprecation.py (+7/-0)
openerp/modules/__init__.py (+3/-7)
openerp/modules/graph.py (+1/-1)
openerp/modules/loading.py (+30/-6)
openerp/modules/module.py (+182/-158)
openerp/modules/registry.py (+30/-17)
openerp/osv/orm.py (+82/-140)
openerp/service/__init__.py (+6/-1)
openerp/tests/addons/test_base_model_a/__init__.py (+3/-0)
openerp/tests/addons/test_base_model_a/__openerp__.py (+15/-0)
openerp/tests/addons/test_base_model_a/models.py (+26/-0)
openerp/tests/addons/test_base_model_a/tests/__init__.py (+13/-0)
openerp/tests/addons/test_base_model_a/tests/test_base_model.py (+40/-0)
openerp/tests/addons/test_base_model_b/__init__.py (+3/-0)
openerp/tests/addons/test_base_model_b/__openerp__.py (+15/-0)
openerp/tests/addons/test_base_model_b/models.py (+18/-0)
openerp/tests/addons/test_base_model_b/tests/__init__.py (+13/-0)
openerp/tests/addons/test_base_model_b/tests/test_base_model.py (+50/-0)
Changed in openobject-server: | |
assignee: | OpenERP's Framework R&D (openerp-dev-framework) → OpenERP Publisher's Warranty Team (openerp-opw) |
tags: | added: maintenance |
Hello qdp,
I have checked your scenario but I think this is not a bug it's behaviour of framework.
You have created a new table(object) through _inherit with another name (stock_picking_in) and main object is stock_picking. Then you have inherit the stock.picking object again (for adding purchase_id field) because you have to set a one2many field picking_ids on purchase order. But here you have assigned a object stock_picking_in (on one2many field). That's it's purchase_id required on stock_picking_in because after inherits the stock.picking it's never affected on stock_picking_in
The reason when mail stock.picking is loaded (stock.py) at that time purchase_id doesn't exist on stock.picking. Then we have _inherit this object with new name, So It will create a new table which consider all the field of stock.picking and add extra-field (Which you have assigned on stock.picking.in) , now both object are loaded. After that on purchase/stock.py you have inherit stock_picking main object and add purchase_id, So It will affect only stock.picking object not the stock.picking.in (which you want). That's why purchase_id doesn't found on stock.picking.in and you have to add it on stock.picking.in.
One most important thing which is the sequence (time of your table creation) of module loading. If you first inherit the stock.picking with adding a purchase_id after that you have create a new table through _inherit with another name this time you are able to see purchase_id on both object.
I am giving you a one small example, I think which is more helpfull.
Class test_test(osv.osv): integer( string= 'Number' , readonly=True, help="List OF Address"), many2one( 'res.users' , 'Manange by', readonly=True),
_name = test.test
_columns = {
'number': fields.
'name': fields.char('Name', size=64, required=True, select=True, help="unique number of the purchase order,computed automatically when the purchase order is created"),
'test' : fields.
}