Add _inherit (ExtendModel) + Inverse fields + sale extends partner
ORM: - ExtendModel(name) retrieves existing model for extension (mirrors Python _inherit without _name). Panics on missing model. - RegisterInverse(fieldName, fn) convenience for computed write-back - Inverse field handling in Write(): caches new value, calls inverse method so computed fields can be written back Sale module: - Extends res.partner with sale_order_ids (O2M) and sale_order_count (computed) via ExtendModel — demonstrates real _inherit pattern Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -276,6 +276,39 @@ func (m *Model) Extend(fields ...*Field) *Model {
|
||||
return m
|
||||
}
|
||||
|
||||
// ExtendModel retrieves an existing model for extension by another module.
|
||||
// Mirrors: Python Odoo's _inherit = 'model.name' (without _name).
|
||||
//
|
||||
// This is the formal mechanism for cross-module model extension. It provides:
|
||||
// 1. Explicit intent (extending vs creating)
|
||||
// 2. Panic on missing model (catch registration order bugs early)
|
||||
// 3. Python Odoo compatibility pattern
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// m := orm.ExtendModel("res.partner")
|
||||
// m.AddFields(orm.Char("industry", orm.FieldOpts{String: "Industry"}))
|
||||
// m.RegisterMethod("action_custom", func(rs *orm.Recordset, args ...interface{}) (interface{}, error) { ... })
|
||||
func ExtendModel(name string) *Model {
|
||||
m := Registry.Get(name)
|
||||
if m == nil {
|
||||
panic(fmt.Sprintf("orm: cannot extend unregistered model %q", name))
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// RegisterInverse registers an inverse method for a computed field.
|
||||
// The method is auto-named "_inverse_<fieldName>" and linked to the field's
|
||||
// Inverse property so that Write() calls it automatically.
|
||||
// Mirrors: odoo/orm/fields.py Field.inverse
|
||||
func (m *Model) RegisterInverse(fieldName string, fn MethodFunc) {
|
||||
inverseName := "_inverse_" + fieldName
|
||||
m.RegisterMethod(inverseName, fn)
|
||||
if f := m.GetField(fieldName); f != nil {
|
||||
f.Inverse = inverseName
|
||||
}
|
||||
}
|
||||
|
||||
// CreateTableSQL generates the CREATE TABLE statement for this model.
|
||||
// Mirrors: odoo/orm/models.py BaseModel._table_exist / init()
|
||||
func (m *Model) CreateTableSQL() string {
|
||||
|
||||
Reference in New Issue
Block a user