Skip to content

HasWorkflowModelMixin

Overview

Model-level utility methods for objects with workflow.

Meta

Source

server/vueda/workflow/models.py:601

_state_permission_rules

Every state rule that applies to this object for groups, keyed by permission codename.

One query resolves every codename the current state grants or denies. has_perm asks about one permission at a time, so a pass evaluating several against one object would otherwise pay a round trip for each.

A codename absent from the mapping has no matching rule, which is the None that check_state_permission returns.

The cache is keyed by caller rather than by the group set, so groups stays a subquery on the rule lookup and never becomes a query of its own. Each new block resolves again, so a caller whose group membership changed is read afresh on its next authorization pass even when the same user instance is reused.

Signature

_state_permission_rules(self, groups, caller)

Parameters

NameTypeRequiredDescription
selfyes
groupscollections.abc.Iterable[str] | collections.abc.Iterable[int] | django.db.models.query.QuerySetyes
callerdjango.db.models.base.Model | Noneyes

Returns

dict[str, bool]

Source

server/vueda/workflow/models.py:823

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

NameTypeRequiredDescription
selfyes
transition<class 'vueda.workflow.models.Transition'>yes
userdoc_app.models.User | Noneyes

Returns

bool | str

Source

server/vueda/workflow/models.py:887

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

NameTypeRequiredDescription
selfyes
transition<class 'vueda.workflow.models.Transition'>yes
userdoc_app.models.User | Noneyes
dry_run<class 'bool'>yes

Returns

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

Source

server/vueda/workflow/models.py:987

apply_transition

Apply a transition to the object.

Signature

apply_transition(self, transition_code, user, dry_run)

Parameters

NameTypeRequiredDescription
selfyes
transition_code<class 'str'>yes
userdoc_app.models.User | Noneyes
dry_run<class 'bool'>yes

Returns

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

Source

server/vueda/workflow/models.py:1001

available_transitions

Returns available transitions for this object.

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

NameTypeRequiredDescription
selfyes
userdoc_app.models.User | Noneyes

Returns

<class 'django.db.models.query.QuerySet'>

Source

server/vueda/workflow/models.py:694

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

NameTypeRequiredDescription
clsyes
objslist[vueda.workflow.models.HasWorkflowModelMixin] | list[int] | django.db.models.query.QuerySetyes
userdoc_app.models.User | Noneyes

Returns

<class 'django.db.models.query.QuerySet'>

Source

server/vueda/workflow/models.py:727

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

NameTypeRequiredDescription
selfyes

Returns

collections.abc.Iterator[None]

Source

server/vueda/workflow/models.py:641

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

NameTypeRequiredDescription
selfyes
perm<class 'str'>yes
groupscollections.abc.Iterable[str] | collections.abc.Iterable[int] | django.db.models.query.QuerySetyes
callerdjango.db.models.base.Model | Noneyes

Returns

bool | None

Source

server/vueda/workflow/models.py:806

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

NameTypeRequiredDescription
selfyes
transition_code<class 'str'>yes
userdoc_app.models.User | Noneyes

Returns

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

Source

server/vueda/workflow/models.py:951

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

NameTypeRequiredDescription
selfyes
transition<class 'vueda.workflow.models.Transition'>yes
userdoc_app.models.User | Noneyes

Returns

<class 'bool'>

Source

server/vueda/workflow/models.py:868

check_workflow_permission

Whether user holds the workflow's configured permissions.

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 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

check_workflow_permission(cls, user, obj)

Parameters

NameTypeRequiredDescription
clsyes
userdoc_app.models.User | Noneyes
objdjango.db.models.base.Model | Noneyes

Returns

<class 'bool'>

Source

server/vueda/workflow/models.py:778

create_object_state

Create a workflow object for this object.

Signature

create_object_state(self)

Parameters

NameTypeRequiredDescription
selfyes

Source

server/vueda/workflow/models.py:623

fast_available_transitions

Returns available transitions for this object without permission checks.

Signature

fast_available_transitions(self)

Parameters

NameTypeRequiredDescription
selfyes

Returns

<class 'django.db.models.query.QuerySet'>

Source

server/vueda/workflow/models.py:712

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

NameTypeRequiredDescription
selfyes
transition_code<class 'str'>yes

Source

server/vueda/workflow/models.py:1010

get_content_type

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

Signature

get_content_type(cls)

Parameters

NameTypeRequiredDescription
clsyes

Returns

<class 'django.contrib.contenttypes.models.ContentType'>

Source

server/vueda/workflow/models.py:635

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

NameTypeRequiredDescription
selfyes
transition_code<class 'str'>yes

Returns

<class 'vueda.workflow.models.Transition'>

Source

server/vueda/workflow/models.py:929

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

NameTypeRequiredDescription
selfyes
transition<class 'vueda.workflow.models.Transition'>yes
userdoc_app.models.User | Noneyes

Returns

<class 'dict'>

Source

server/vueda/workflow/models.py:917

on_transition

Override this method to add custom logic on transition.

Signature

on_transition(self, transition, user, dry_run)

Parameters

NameTypeRequiredDescription
selfyes
transition<class 'vueda.workflow.models.Transition'>yes
userdoc_app.models.User | Noneyes
dry_run<class 'bool'>yes

Source

server/vueda/workflow/models.py:1039

on_transition_ignored

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

Signature

on_transition_ignored(self, transition, user)

Parameters

NameTypeRequiredDescription
selfyes
transition<class 'vueda.workflow.models.Transition'>yes
userdoc_app.models.User | Noneyes

Source

server/vueda/workflow/models.py:1044

save

Save the object and create a workflow object if it doesn't exist.

Signature

save(self, args, kwargs)

Parameters

NameTypeRequiredDescription
selfyes
argsyes
kwargsyes

Source

server/vueda/workflow/models.py:615

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

NameTypeRequiredDescription
selfyes
transition<class 'vueda.workflow.models.Transition'>yes

Returns

<class 'bool'>

Source

server/vueda/workflow/models.py:941

update_object_state

Sets the history user to the system user if a user isn't passed in.

Signature

update_object_state(self, state, user, change_reason)

Parameters

NameTypeRequiredDescription
selfyes
stateyes
useryes
change_reasonyes

Source

server/vueda/workflow/models.py:1028

_meta

_workflow_state_cache

object_state

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

Source

server/vueda/workflow/models.py:676

object_states_proxy

Accessor to the related objects manager on the one-to-many relation created by GenericRelation.

In the example::

class Post(Model):
    comments = GenericRelation(Comment)

post.comments is a ReverseGenericManyToOneDescriptor instance.

workflow

Return the Workflow configured for this model, or None if none exists.

Source

server/vueda/workflow/models.py:665

workflow_state

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

Source

server/vueda/workflow/models.py:688

Source

server/vueda/workflow/models.py:588

Documents matching: server v3.0.0a1.post1client v3.0.0-alpha.2