Skip to main content

Controller Lifecycle Hooks

Auto-generated from source code - Do not edit manually.

Controllers handle business logic through lifecycle hooks. Override these methods in your controller subclass.


Hook Reference

BaseController

validate

async def validate(context: Any) -> None

Validate document before any save operation.

    Called before insert and update. Raise exceptions for validation errors.

Args:
context: Optional context (user info, request metadata, etc.)

before_insert

async def before_insert(context: Any) -> None

Hook called before inserting a new document.

    Use for setting defaults, generating values, etc.

Args:
context: Optional context (user info, request metadata, etc.)

after_insert

async def after_insert(context: Any) -> None

Hook called after successfully inserting a new document.

    Use for side effects like notifications, logging, etc.

Args:
context: Optional context (user info, request metadata, etc.)

after_naming

async def after_naming(context: Any) -> None

Hook called after the document has been named and inserted.

    This guarantees that self.doc.name is set to the final value.

Args:
context: Optional context (user info, request metadata, etc.)

before_save

async def before_save(context: Any) -> None

Hook called before saving (insert or update).

    Called after validate, before database write.

Args:
context: Optional context (user info, request metadata, etc.)

after_save

async def after_save(context: Any) -> None

Hook called after successfully saving a document.

    Use for cache invalidation, event publishing, etc.

Args:
context: Optional context (user info, request metadata, etc.)

before_delete

async def before_delete(context: Any) -> None

Hook called before deleting a document.

    Use for validation, preventing deletion of linked docs, etc.

Args:
context: Optional context (user info, request metadata, etc.)

after_delete

async def after_delete(context: Any) -> None

Hook called after successfully deleting a document.

    Use for cleanup, cascade operations, etc.

Args:
context: Optional context (user info, request metadata, etc.)

on_submit

async def on_submit(context: Any) -> None

Hook called when a submittable document is submitted.

    Only applies to DocTypes with SubmittableMixin.

Args:
context: Optional context (user info, request metadata, etc.)

on_cancel

async def on_cancel(context: Any) -> None

Hook called when a submittable document is cancelled.

    Only applies to DocTypes with SubmittableMixin.

Args:
context: Optional context (user info, request metadata, etc.)

check_permission

async def check_permission(action: str, doc_id: str | None) -> bool

Check if current user has permission for an action.

    Simple helper that builds PolicyEvaluateRequest internally.
Returns bool instead of raising - use require_permission() to raise.

Requires the controller to have:
- `user: UserContext` attribute
- `doctype_name: str` attribute
- `permission: PermissionProtocol` attribute (injected via DI)

Args:
action: Action to check (read, write, create, delete)
doc_id: Optional document ID for resource-level checks

Returns:
True if authorized, False otherwise

Example:
if await self.check_permission("write"):
# User can write
...

require_permission

async def require_permission(action: str, doc_id: str | None) -> None

Require that user has permission for an action, raising if not.

    Similar to check_permission() but raises PermissionDeniedError
instead of returning False.

Args:
action: Action to check (read, write, create, delete)
doc_id: Optional document ID for resource-level checks

Raises:
PermissionDeniedError: If user is not authorized

Example:
await self.require_permission("write")
# If we get here, user is authorized