or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

dynamic-states.mdexceptions.mdfield-types.mdindex.mdmodel-mixins.mdsignals.mdtransitions.mdvisualization.md

index.mddocs/

0

# Django FSM

1

2

Django FSM provides declarative finite state machine support for Django models through FSMField and the @transition decorator. It enables developers to manage model state transitions in a structured way by decorating methods that can contain side-effects of state changes, supports conditional transitions with permission checking, optimistic locking to prevent concurrent state modifications, and state-based proxy model switching.

3

4

## Package Information

5

6

- **Package Name**: django-fsm

7

- **Language**: Python

8

- **Installation**: `pip install django-fsm`

9

10

## Core Imports

11

12

```python

13

from django_fsm import FSMField, transition

14

```

15

16

Common additional imports:

17

18

```python

19

from django_fsm import (

20

FSMField, FSMIntegerField, FSMKeyField,

21

transition, can_proceed, has_transition_perm,

22

TransitionNotAllowed, ConcurrentTransition, InvalidResultState,

23

FSMModelMixin, ConcurrentTransitionMixin,

24

GET_STATE, RETURN_VALUE

25

)

26

```

27

28

For signals:

29

30

```python

31

from django_fsm.signals import pre_transition, post_transition

32

```

33

34

## Basic Usage

35

36

```python

37

from django.db import models

38

from django_fsm import FSMField, transition

39

40

class BlogPost(models.Model):

41

state = FSMField(default='new')

42

title = models.CharField(max_length=200)

43

content = models.TextField()

44

45

@transition(field=state, source='new', target='published')

46

def publish(self):

47

"""

48

This method may contain side-effects like

49

updating caches, notifying users, etc.

50

"""

51

pass

52

53

@transition(field=state, source='published', target='archived')

54

def archive(self):

55

pass

56

57

# Usage example

58

blog_post = BlogPost.objects.create(title="My Post", content="Content")

59

print(blog_post.state) # 'new'

60

61

blog_post.publish()

62

blog_post.save()

63

print(blog_post.state) # 'published'

64

65

# Check if transition is possible before calling

66

from django_fsm import can_proceed

67

68

if can_proceed(blog_post.archive):

69

blog_post.archive()

70

blog_post.save()

71

```

72

73

## Architecture

74

75

Django FSM uses a decorator-based approach to define state machines:

76

77

- **FSM Fields**: Special Django model fields that store state and provide transition management

78

- **Transition Decorator**: Marks methods as state transitions with source/target configuration

79

- **Meta Information**: Internal tracking of transitions, conditions, and permissions

80

- **Signal System**: Hooks for pre/post transition events

81

- **Optimistic Locking**: Protection against concurrent state modifications

82

83

The library integrates seamlessly with Django's ORM and provides dynamic methods for each FSM field to query available transitions.

84

85

## Capabilities

86

87

### Field Types and Configuration

88

89

Core FSM field types for different data storage needs: CharField-based FSMField, IntegerField-based FSMIntegerField, and ForeignKey-based FSMKeyField. Includes configuration options for default states, protection against direct modification, and state-based proxy model switching.

90

91

```python { .api }

92

class FSMField(FSMFieldMixin, models.CharField):

93

def __init__(self, default=None, protected=False, state_choices=None, max_length=50, **kwargs): ...

94

95

class FSMIntegerField(FSMFieldMixin, models.IntegerField):

96

def __init__(self, default=None, protected=False, state_choices=None, **kwargs): ...

97

98

class FSMKeyField(FSMFieldMixin, models.ForeignKey):

99

def __init__(self, to, default=None, protected=False, state_choices=None, **kwargs): ...

100

```

101

102

[Field Types](./field-types.md)

103

104

### Transition Management

105

106

Decorator for marking methods as state transitions with comprehensive configuration options including source/target states, error handling, conditions, permissions, and custom metadata. Also includes utility functions to check transition availability and permissions.

107

108

```python { .api }

109

def transition(field, source="*", target=None, on_error=None, conditions=[], permission=None, custom={}): ...

110

111

def can_proceed(bound_method, check_conditions=True): ...

112

113

def has_transition_perm(bound_method, user): ...

114

```

115

116

[Transitions](./transitions.md)

117

118

### Model Mixins and Advanced Features

119

120

Model mixins for enhanced FSM functionality including refresh_from_db support for protected fields and optimistic locking protection against concurrent transitions. These mixins provide additional safety and reliability features for production applications.

121

122

```python { .api }

123

class FSMModelMixin(object):

124

def refresh_from_db(self, *args, **kwargs): ...

125

126

class ConcurrentTransitionMixin(object):

127

def save(self, *args, **kwargs): ...

128

```

129

130

[Model Mixins](./model-mixins.md)

131

132

### Exception Handling

133

134

Exception classes for managing state transition errors including general transition failures, concurrent modification conflicts, and invalid result states. Proper exception handling is essential for robust state machine implementations.

135

136

```python { .api }

137

class TransitionNotAllowed(Exception):

138

def __init__(self, *args, object=None, method=None, **kwargs): ...

139

140

class ConcurrentTransition(Exception): ...

141

142

class InvalidResultState(Exception): ...

143

```

144

145

[Exception Handling](./exceptions.md)

146

147

### Signal System and Events

148

149

Django signals for hooking into state transition lifecycle events, enabling custom logic before and after transitions. Signals provide a clean way to implement cross-cutting concerns like logging, notifications, and audit trails.

150

151

```python { .api }

152

# From django_fsm.signals

153

pre_transition = Signal()

154

post_transition = Signal()

155

```

156

157

[Signals](./signals.md)

158

159

### Dynamic State Classes

160

161

Classes for dynamic state resolution allowing transition targets to be determined at runtime based on method return values or custom functions. This enables flexible state machines that can adapt to different business logic scenarios.

162

163

```python { .api }

164

class RETURN_VALUE(State):

165

def __init__(self, *allowed_states): ...

166

167

class GET_STATE(State):

168

def __init__(self, func, states=None): ...

169

```

170

171

[Dynamic States](./dynamic-states.md)

172

173

### Visualization and Management

174

175

Django management command for creating GraphViz visualizations of state machine transitions, helping developers understand and document complex state workflows. The command generates dot files that can be rendered as images or interactive graphs.

176

177

```python { .api }

178

# Management command

179

python manage.py graph_transitions [appname[.model[.field]]] --output file.png --layout dot

180

```

181

182

[Visualization](./visualization.md)