---
# GENERATED FILE — do not edit.
# Source: `manage.py docs_generate` (djust 1.2.2).
# Edit the generator in docs_app/generator.py instead.
title: "Decorators"
description: "Decorators on the LiveView base class, generated."
level: reference
order: 30
section: reference
generated: true
---
Decorators on `LiveView`, generated from the framework manifest.

**11 entries.**

## `@cache`

```python
from djust.decorators import cache
```

Client-side response caching with TTL.

**Example**

```python
@cache(ttl=60, key_params=['query'])
def search(self, query: str = '', **kwargs):
    ...
```

| Parameter | Meaning |
| --- | --- |
| `ttl` | int — cache time-to-live in seconds (default: 60) |
| `key_params` | Optional[List[str]] — params to include in cache key |

## `@client_state`

```python
from djust.decorators import client_state
```

INERT / MARKER ONLY — stamps metadata that nothing in the shipped client reads, so a decorated handler behaves exactly like an undecorated one. The StateBus class that was to consume it was deleted in #2680 as dead code; whether to implement the client half is #2680. Do not recommend it as a working coordination mechanism.

**Example**

```python
@client_state(keys=['filter'])  # INERT (#2680): publishes nothing
def update_filter(self, filter: str = '', **kwargs):
    ...
```

| Parameter | Meaning |
| --- | --- |
| `keys` | List[str] — state keys to publish/subscribe |

## `@computed`

```python
from djust.decorators import computed
```

Computed property derived from state. Available in templates, auto-recalculated when state changes.

**Example**

```python
@computed
def count_doubled(self):
    return self.count * 2
```

## `@debounce`

```python
from djust.decorators import debounce
```

Client-side debounce: the browser delays the send until `wait` seconds after the LAST event, so a burst of keystrokes reaches the server as one event carrying the last payload. `max_wait` forces a send while a burst is still arriving. Implemented in src/05-handler-rate-limit.js (#2656).

**Example**

```python
@debounce(wait=0.5)
def search(self, query: str = '', **kwargs):
    ...
```

| Parameter | Meaning |
| --- | --- |
| `wait` | float — seconds to wait (default: 0.3) |
| `max_wait` | Optional[float] — max seconds before forcing execution |

## `@event_handler`

```python
from djust.decorators import event_handler
```

Mark method as an event handler with automatic signature introspection. Extracts params, types, and descriptions from the function signature.

**Example**

```python
@event_handler
def search(self, value: str = '', **kwargs):
    ...
```

**Example**

```python
@event_handler(description='Update quantity')
def update_item(self, item_id: int, quantity: int, **kwargs):
    ...
```

| Parameter | Meaning |
| --- | --- |
| `params` | Optional[List[str]] — explicit parameter list (overrides auto-extraction) |
| `description` | str — human-readable description (overrides docstring) |
| `coerce_types` | bool — auto-coerce string params to expected types (default: True) |

## `@optimistic`

```python
from djust.decorators import optimistic
```

INERT — stamps metadata nothing in the shipped client reads, and a bare @optimistic declares no DOM change for a client to apply, so the UI does not update before the server responds. Whether to implement it (or fold it into the wired DEP-002 optimistic_rules) is #2699. Do not recommend it as a working mechanism.

**Example**

```python
@optimistic  # INERT (#2699): the UI does not update early
def toggle_todo(self, todo_id: int = 0, **kwargs):
    ...
```

## `@permission_required`

```python
from djust.decorators import permission_required
```

Require Django permission(s) to call this handler. Checked server-side before execution.

**Example**

```python
@permission_required("myapp.delete_item")
@event_handler()
def delete_item(self, item_id: int, **kwargs):
    ...
```

| Parameter | Meaning |
| --- | --- |
| `perm` | Union[str, List[str]] — Django permission string(s) |

## `@rate_limit`

```python
from djust.decorators import rate_limit
```

Server-side rate limiting using token bucket algorithm.

**Example**

```python
@rate_limit(rate=5, burst=3)
@event_handler
def expensive_op(self, **kwargs):
    ...
```

| Parameter | Meaning |
| --- | --- |
| `rate` | float — tokens per second (default: 10) |
| `burst` | int — maximum burst capacity (default: 5) |

## `@reactive`

```python
from djust.decorators import reactive
```

Create a reactive property that triggers re-render on change.

**Example**

```python
@reactive
def count(self):
    return self._count
```

## `@throttle`

```python
from djust.decorators import throttle
```

Client-side throttle: at most one send per `interval`. Both edges are honoured by default — the first event of a window sends immediately and events inside the window collapse into one trailing send carrying the last payload. Implemented in src/05-handler-rate-limit.js (#2656).

**Example**

```python
@throttle(interval=0.1)
def on_scroll(self, scroll_y: int = 0, **kwargs):
    ...
```

| Parameter | Meaning |
| --- | --- |
| `interval` | float — minimum interval in seconds (default: 0.1) |
| `leading` | bool — execute on leading edge (default: True) |
| `trailing` | bool — execute on trailing edge (default: True) |

## `state()`

```python
from djust.decorators import state
```

Descriptor for reactive state. Cleaner than setting attributes in mount(). Automatically included in context and triggers re-renders.

**Example**

```python
count = state(default=0)
message = state(default='Hello')
```

| Parameter | Meaning |
| --- | --- |
| `default` | Any — default value for the state property |

## Put decorators in context

Read [Events](/core-concepts/events/) for handler binding and argument extraction,
[State primitives](/guides/state-primitives/) for computed values, and
[Authorization](/guides/authorization/) for permission checks.
