Extending an existing module
The first walkthrough builds a module from nothing. This one does the other half of the job, and it is the half you will do most often: a module already exists, it almost does what you need, and you are three fields and one rule short.
The wrong answer is to copy it and edit the copy. The day its next version ships, you have two codebases to reconcile and nobody to do it.
What we are going to build
pipeline is the deals module: leads, stages, forecasts. It knows nothing about the
competition, which is the first question of any pipeline review: who were we up against,
and who won?
We add a pipeline_rivals module that:
- brings its own model,
rivals_competitor; - adds two fields to
pipeline_lead, without touchingpipeline’s code; - completes
pipeline’s screens instead of replacing them; - reacts to what happens in
pipelinewithout ever importing it.
At the end, a deal’s form carries “Up against” and “Lost to”, the list carries one more
column, and pipeline has not changed by a line.
The rule that holds it all together
A business module never imports another business module. That is interdiction no. 8 in
CLAUDE.md, and it is not a style preference: an import modules.pipeline ties you to its
internal functions, which nobody promised to keep. You depend on it, it does not know, and its
next version breaks you.
What you do name are public facts:
| You name | You do not name |
|---|---|
a model (pipeline_lead) | the Python module behind it |
a field (state, source_id) | the function computing it |
an event (record.updated) | the line emitting it |
a group code (pipeline_manager) | the group object |
Everything else in this walkthrough follows from that.
What you need at hand
An instance with pipeline installed and activated, and at least a skim of the first
walkthrough: what a model, a view or a translation file is does not get explained again here.
The steps
| 1 | The extension module | The manifest, the dependency, and what we do not write. |
| 2 | Adding fields | Contributing to a model that is not yours. |
| 3 | Completing a screen | A patch, not a replacement. |
| 4 | Reacting, and leaving | Listening without importing, and uninstalling cleanly. |