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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| transition | vueda.workflow.models.Transition | yes | ||
| user | doc_app.models.User | None | no | None |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| transition | vueda.workflow.models.Transition | yes | ||
| user | doc_app.models.User | None | no | None | |
| dry_run | bool | no | False |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| transition_code | str | yes | ||
| user | doc_app.models.User | None | no | None | |
| dry_run | bool | no | False |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| user | doc_app.models.User | None | no | None |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| cls | yes | |||
| objs | list['WorkflowModelMethods'] | list[int] | django.db.models.query.QuerySet | yes | ||
| user | doc_app.models.User | None | no | None |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| perm | str | yes | ||
| groups | collections.abc.Iterable[str] | collections.abc.Iterable[int] | django.db.models.query.QuerySet | yes | ||
| caller | django.db.models.base.Model | None | no | None |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| transition_code | str | yes | ||
| user | doc_app.models.User | None | no | None |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| transition | vueda.workflow.models.Transition | yes | ||
| user | doc_app.models.User | None | no | None |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| cls | yes | |||
| user | doc_app.models.User | None | no | None | |
| obj | django.db.models.base.Model | None | no | None |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| transition_code | str | yes |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| cls | yes |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| transition_code | str | yes |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| transition | vueda.workflow.models.Transition | yes | ||
| user | doc_app.models.User | None | no | None |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| cls | yes | |||
| user | doc_app.models.User | None | no | None | |
| obj | django.db.models.base.Model | None | no | None |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| transition | vueda.workflow.models.Transition | yes | ||
| user | doc_app.models.User | None | no | None | |
| dry_run | bool | no | False |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| transition | vueda.workflow.models.Transition | yes | ||
| user | doc_app.models.User | None | no | None |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| transition | vueda.workflow.models.Transition | yes |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| state | yes |
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