Skip to content

WorkflowModelMethods ​

Overview ​

Model-level utility methods for objects with workflow.

A model does not subclass this directly. class Vueda.Workflow with enabled = True makes the workflow app append it to the model's bases once Django prepares the model, so it sits last in the method resolution order. A method the model or any of its bases defines takes precedence, and an override can still call super() to reach the default here.

allow_transition ​

Check if transition is allowed for this object. return falsy or a string will raise a InvalidTransitionError exception in apply_transition

Resolves only transition. The cost does not grow with the number of other transitions leaving the current state. Use available_transitions when the permitted set itself is what is wanted.

Signature ​

allow_transition(self, transition, user)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
transitionvueda.workflow.models.Transitionyes
userdoc_app.models.User | NonenoNone

Returns ​

bool | str

Source ​

server/vueda/workflow/models.py:950

apply_checked_transition ​

Write an already-authorized transition (as returned by check_transition) without re-checking permissions or availability.

Returns the target state and the object state's new revision, which is None when the object has no state row to record.

Signature ​

apply_checked_transition(self, transition, user, dry_run)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
transitionvueda.workflow.models.Transitionyes
userdoc_app.models.User | NonenoNone
dry_runboolnoFalse

Returns ​

tuple[vueda.workflow.models.State, str | None]

Source ​

server/vueda/workflow/models.py:1045

apply_transition ​

Apply a transition to the object.

Signature ​

apply_transition(self, transition_code, user, dry_run)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
transition_codestryes
userdoc_app.models.User | NonenoNone
dry_runboolnoFalse

Returns ​

tuple[vueda.workflow.models.State, str | None]

Source ​

server/vueda/workflow/models.py:1060

available_transitions ​

Returns available transitions for this object.

Empty when user does not hold the workflow's configured permissions for this object (see has_workflow_permission), including when the workflow configures none.

The whole pass runs inside one cached_workflow_state() block, so the object's workflow, current state, and state rules are read once rather than once per candidate transition.

Signature ​

available_transitions(self, user)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
userdoc_app.models.User | NonenoNone

Returns ​

django.db.models.query.QuerySet

Source ​

server/vueda/workflow/models.py:747

available_transitions_for ​

Returns available transitions for a list of objects.

A transition is available when at least one of objs sits in one of its source states and user may take it on that object. This matches the source-state filter, which admits a transition leaving any of the objects' states rather than all of them.

check_transition_permission resolves user.has_perms(perms, obj=...), so the answer depends on the object it receives. This classmethod therefore loads the concrete instances and asks each candidate object rather than asking the model class.

Signature ​

available_transitions_for(cls, objs, user)

Parameters ​

NameTypeRequiredDefaultDescription
clsyes
objslist['WorkflowModelMethods'] | list[int] | django.db.models.query.QuerySetyes
userdoc_app.models.User | NonenoNone

Returns ​

django.db.models.query.QuerySet

Source ​

server/vueda/workflow/models.py:783

cached_workflow_state ​

Hold this object's workflow and object_state for the duration of the block.

One authorization pass reads both repeatedly: check_state_permission resolves the current state for every permission it is asked about, and VuedaUserMixin.has_perm reads the workflow to decide whether state rules apply at all. Without this, each read is a fresh query.

The cache is scoped to a block rather than to the instance on purpose. execute_transition checks a transition, takes a row lock, and checks again against the locked row, and that second check has to observe any state written in between. Nested blocks reuse the outermost cache and leave it to the outermost block to clear.

Signature ​

cached_workflow_state(self)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes

Returns ​

collections.abc.Iterator[None]

Source ​

server/vueda/workflow/models.py:694

check_state_permission ​

Check whether the object's current state grants or denies perm for any of groups. Returns True (grant), False (deny), or None (no state rule applies). When multiple rules match, deny takes precedence over grant.

caller is the user groups belongs to. Passing it lets one cached_workflow_state() block resolve that caller's rules once instead of once per permission. Without it every call resolves, which is what an uncached caller gets.

Signature ​

check_state_permission(self, perm, groups, caller)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
permstryes
groupscollections.abc.Iterable[str] | collections.abc.Iterable[int] | django.db.models.query.QuerySetyes
callerdjango.db.models.base.Model | NonenoNone

Returns ​

bool | None

Source ​

server/vueda/workflow/models.py:869

check_transition ​

Validate that transition_code can be applied by user, without writing anything.

Performs the same permission and allow_transition checks as apply_transition (raising the same exceptions), and resolves the effective user (falling back to the acting user the history middleware records on the action, then the system user, exactly as apply_transition does). Callers that need to gate a transition on warnings (see get_transition_warnings) before writing should call this first, then apply_checked_transition.

Signature ​

check_transition(self, transition_code, user)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
transition_codestryes
userdoc_app.models.User | NonenoNone

Returns ​

tuple[vueda.workflow.models.Transition, doc_app.models.User]

Source ​

server/vueda/workflow/models.py:1009

check_transition_permission ​

user as None means superuser, pass django's AnonymousUser if you want to check for anonymous user.

Signature ​

check_transition_permission(self, transition, user)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
transitionvueda.workflow.models.Transitionyes
userdoc_app.models.User | NonenoNone

Returns ​

bool

Source ​

server/vueda/workflow/models.py:931

check_workflow_permission ​

Return True when user holds the workflow's configured permissions, else raise PermissionDenied.

See has_workflow_permission for the decision.

Signature ​

check_workflow_permission(cls, user, obj)

Parameters ​

NameTypeRequiredDefaultDescription
clsyes
userdoc_app.models.User | NonenoNone
objdjango.db.models.base.Model | NonenoNone

Returns ​

bool

Source ​

server/vueda/workflow/models.py:857

create_object_state ​

Create a workflow object for this object.

Signature ​

create_object_state(self)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes

Source ​

server/vueda/workflow/models.py:677

fast_available_transitions ​

Returns available transitions for this object without permission checks.

Signature ​

fast_available_transitions(self)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes

Returns ​

django.db.models.query.QuerySet

Source ​

server/vueda/workflow/models.py:768

fast_transition ​

Apply a transition without permission checks. Raises InvalidTransitionError if the transition is not available from the current state, unless the TransitionSource is marked ignored, in which case on_transition_ignored is called.

Signature ​

fast_transition(self, transition_code)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
transition_codestryes

Source ​

server/vueda/workflow/models.py:1069

get_content_type ​

Return the ContentType for this model class. Result is cached by Django.

Signature ​

get_content_type(cls)

Parameters ​

NameTypeRequiredDefaultDescription
clsyes

Returns ​

django.contrib.contenttypes.models.ContentType

Source ​

server/vueda/workflow/models.py:688

get_transition ​

Return the Transition with the given code in this object's workflow. Raises Transition.DoesNotExist if not found.

Signature ​

get_transition(self, transition_code)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
transition_codestryes

Returns ​

vueda.workflow.models.Transition

Source ​

server/vueda/workflow/models.py:986

get_transition_warnings ​

Hook returning advisory warnings for a transition, consulted before it is written.

Override to report warnings that should gate the transition behind confirmation (HTTP 409) without denying it outright the way allow_transition does. Return the aggregate {field: [messages]} warnings dict (use "non_field_errors" for warnings not tied to a field). The default returns {}, meaning no confirmation is required. See vueda.core.exceptions.gate_warnings for how the caller turns this into a 409.

Signature ​

get_transition_warnings(self, transition, user)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
transitionvueda.workflow.models.Transitionyes
userdoc_app.models.User | NonenoNone

Returns ​

dict

Source ​

server/vueda/workflow/models.py:974

has_workflow_permission ​

Whether user holds the workflow's configured permissions.

The one decision behind check_workflow_permission, available_transitions, and available_transitions_for, so the endpoints and the valid_transitions field agree.

user as None means programmatic use; pass Django's AnonymousUser to check an anonymous request. obj scopes the check to one object, so an object permission backend decides the configured workflow permissions the way it decides the target model's own. A workflow with no configured permissions denies every user, superusers included.

A state rule is not a substitute for a configured workflow permission. State rules apply where a concrete object supplies the state, which is the object permission decision this check passes obj to, not a reason to skip the check.

Signature ​

has_workflow_permission(cls, user, obj)

Parameters ​

NameTypeRequiredDefaultDescription
clsyes
userdoc_app.models.User | NonenoNone
objdjango.db.models.base.Model | NonenoNone

Returns ​

bool

Source ​

server/vueda/workflow/models.py:828

on_transition ​

Override this method to add custom logic on transition.

Signature ​

on_transition(self, transition, user, dry_run)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
transitionvueda.workflow.models.Transitionyes
userdoc_app.models.User | NonenoNone
dry_runboolnoFalse

Source ​

server/vueda/workflow/models.py:1099

on_transition_ignored ​

Override this method to add custom logic when a transition is intentionally ignored.

Signature ​

on_transition_ignored(self, transition, user)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
transitionvueda.workflow.models.Transitionyes
userdoc_app.models.User | NonenoNone

Source ​

server/vueda/workflow/models.py:1104

should_ignore_transition_from_state ​

Return True if the transition should be treated as a no-op from the current state.

Signature ​

should_ignore_transition_from_state(self, transition)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
transitionvueda.workflow.models.Transitionyes

Returns ​

bool

Source ​

server/vueda/workflow/models.py:999

update_object_state ​

Write state as this object's current state.

The write joins the open action. apply_checked_transition and fast_transition open one named after the transition when no action is open.

Signature ​

update_object_state(self, state)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
stateyes

Source ​

server/vueda/workflow/models.py:1088

object_state ​

Return the ObjectState record for this instance, or None if not yet created.

Source ​

server/vueda/workflow/models.py:729

workflow ​

Return the Workflow configured for this model. Raises WorkflowNotConfiguredError if none exists.

Source ​

server/vueda/workflow/models.py:718

workflow_state ​

Return the current State for this instance, or None if no state exists.

Source ​

server/vueda/workflow/models.py:741

Source ​

server/vueda/workflow/models.py:664