angee.graphql.publishing
Model-change event publishing over the channel layer for GraphQL subscriptions.
change_published
Sent robustly after commit when a model change should be observed.
Receivers are called with sender set to the model class and a payload keyword containing the already-built :class:ChangePayload. Delivery uses send_robust: receiver exceptions are logged by the publisher and are not propagated to the save/delete caller or allowed to starve later receivers.
mute_changes
@contextmanager
def mute_changes() -> Iterator[None]Suppress per-row change publishing for the duration of the block.
A bulk teardown that deletes thousands of rows fires one post_delete publisher per row; each would lazy-load the row's thread and run an exists() probe inside broadcasts_changes() before buffering an on_commitgroup_send. While a whole scope is being purged those per-row events are noise (and their N+1 defeats a count-only preview's scale win), so :func:publish_change returns immediately when muted — skipping both the probe and the broadcast. Thread-local and reentrant, and the prior depth is restored in finally so a nested or failing block never leaks the muted state. This is not :func:disconnect_publishers: it does not touch the shared signal registry, so it is safe under concurrent requests. A coarse-grained change the caller still wants observed (the purged root's own row) must run outside the block.
change_group
def change_group(model: type[models.Model]) -> strReturn the channel-layer group name for model changes.
connect_publishers
def connect_publishers(model: type[models.Model],
*,
readable_fields: Iterable[str] = ()) -> NoneConnect save/delete publishers with the model's readable projection.
disconnect_publishers
def disconnect_publishers(model: type[models.Model]) -> boolDisconnect model's save and delete publishers; return whether any were wired.
The public inverse of :func:connect_publishers — a test that wires a lone publisher to observe a broadcast restores prior state through this seam instead of re-deriving the private dispatch-uid format or probing receiver tuples.
connect_change_broadcast_receiver
def connect_change_broadcast_receiver() -> NoneConnect the GraphQL channel-layer broadcast receiver exactly once.
change_channel_layer
def change_channel_layer() -> AnyReturn the configured channel layer after validating deployment safety.
publish_change
def publish_change(
instance: models.Model,
*,
action: str,
update_fields: Iterable[str] | None,
readable_fields: Iterable[str] = ()
) -> NoneBuild and send one observable change payload after commit.