Start here. This is the direct spoken answer to practice first.
Overview
Signals are useful extension hooks, but they are a poor default for an in-project workflow.
I prefer an explicit function call when the sender and receiver are part of the same application workflow. It makes ordering, inputs, failures, and tests visible. A signal is more appropriate when the sender should expose an event to optional or separately owned receivers without knowing them directly. Django's own guidance warns that signals can make code harder to understand and debug.