Skip to content

Commit 25fd79a

Browse files
committed
Ref #22 -- Simplify tutorial by joining state and behavior
1 parent 8851196 commit 25fd79a

File tree

7 files changed

+56
-61
lines changed

7 files changed

+56
-61
lines changed

docs/index.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,14 @@ may look like:
4141
from joeflow import tasks
4242
4343
44-
class Shipment(Workflow):
44+
class ShippingWorkflow(Workflow):
45+
46+
# model fields to store the state
4547
email = models.EmailField(blank=True)
4648
shipping_address = models.TextField()
4749
tracking_code = models.TextField()
4850
49-
class ShippingWorkflow(Shipment):
51+
# tasks (nodes)
5052
checkout = tasks.StartView(fields=["shipping_address", "email"])
5153
5254
ship = tasks.UpdateView(fields=["tracking_code"])
@@ -66,6 +68,7 @@ may look like:
6668
def end(self):
6769
pass
6870
71+
# edges
6972
edges = [
7073
(checkout, ship),
7174
(ship, has_email),
@@ -74,9 +77,6 @@ may look like:
7477
(send_tracking_code, end),
7578
]
7679
77-
class Meta:
78-
proxy = True
79-
8080
Design Principles
8181
=================
8282

docs/tutorial/workflow.rst

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,27 +32,32 @@ store a user. Like so:
3232
from joeflow.models import Workflow
3333
3434
35-
class WelcomeWorkflowState(Workflow):
35+
class WelcomeWorkflow(Workflow):
36+
# state
3637
user = models.ForeignKey(
3738
settings.AUTH_USER_MODEL,
3839
on_delete=models.CASCADE,
3940
blank=True, null=True,
4041
)
4142
42-
43-
We keep the model abstract. The abstract model will make it easier to separate
44-
state from behavior and therefore easier to read for your fellow developers.
45-
4643
Next we add the behavior:
4744

4845
.. code-block:: python
4946
47+
from django.conf import settings
5048
from joeflow import tasks
49+
from joeflow.models import Workflow
5150
52-
from . import models
5351
52+
class WelcomeWorkflow(Workflow):
53+
# state
54+
user = models.ForeignKey(
55+
settings.AUTH_USER_MODEL,
56+
on_delete=models.CASCADE,
57+
blank=True, null=True,
58+
)
5459
55-
class WelcomeWorkflow(models.WelcomeWorkflowState):
60+
# behavior
5661
start = tasks.StartView(fields=["user"])
5762
5863
def has_user(self):
@@ -76,8 +81,6 @@ Next we add the behavior:
7681
(send_welcome_email, end),
7782
]
7883
79-
class Meta:
80-
proxy = True
8184
8285
We have the tasks ``start``, ``has_user`` ``send_welcome_email`` and ``end``
8386
on the top and define all the edges on the bottom. Edges are defined by a
@@ -101,11 +104,11 @@ to your ``urls.py``:
101104
102105
from django.urls import path, include
103106
104-
from . import workflows
107+
from . import models
105108
106109
urlpatterns = [
107110
#
108-
path('welcome/', include(workflows.WelcomeWorkflow.urls())),
111+
path('welcome/', include(models.WelcomeWorkflow.urls())),
109112
]
110113
111114
This will add URLs for all human tasks as well as a detail view and manual

tests/test_docs.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from django.test import SimpleTestCase, TestCase
44
from django.urls import reverse
55

6-
from .testapp import workflows
6+
from .testapp import models
77

88

99
class WelcomeWorkflowMachineTest(SimpleTestCase):
@@ -14,11 +14,11 @@ def test_has_user__with_user(self):
1414
last_name="Parker",
1515
username="spidy",
1616
)
17-
workflow = workflows.WelcomeWorkflow(user=user)
17+
workflow = models.WelcomeWorkflow(user=user)
1818
self.assertEqual(workflow.has_user(), [workflow.send_welcome_email])
1919

2020
def test_has_user__without_user(self):
21-
workflow = workflows.WelcomeWorkflow()
21+
workflow = models.WelcomeWorkflow()
2222
self.assertEqual(workflow.has_user(), [workflow.end])
2323

2424
def test_send_welcome_email(self):
@@ -28,7 +28,7 @@ def test_send_welcome_email(self):
2828
last_name="Parker",
2929
username="spidy",
3030
)
31-
workflow = workflows.WelcomeWorkflow(user=user)
31+
workflow = models.WelcomeWorkflow(user=user)
3232

3333
workflow.send_welcome_email()
3434

@@ -55,13 +55,13 @@ def test_start__post_with_user(self):
5555

5656
response = self.client.post(self.start_url, data=dict(user=user.pk))
5757
self.assertEqual(response.status_code, 302)
58-
workflow = workflows.WelcomeWorkflow.objects.get()
58+
workflow = models.WelcomeWorkflow.objects.get()
5959
self.assertTrue(workflow.user)
6060
self.assertTrue(workflow.task_set.succeeded().filter(name="start").exists())
6161

6262
def test_start__post_without_user(self):
6363
response = self.client.post(self.start_url)
6464
self.assertEqual(response.status_code, 302)
65-
workflow = workflows.WelcomeWorkflow.objects.get()
65+
workflow = models.WelcomeWorkflow.objects.get()
6666
self.assertFalse(workflow.user)
6767
self.assertTrue(workflow.task_set.succeeded().filter(name="start").exists())

tests/testapp/migrations/0001_initial.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ class Migration(migrations.Migration):
158158
bases=("joeflow.workflow",),
159159
),
160160
migrations.CreateModel(
161-
name="WelcomeWorkflowState",
161+
name="WelcomeWorkflow",
162162
fields=[
163163
(
164164
"workflow_ptr",
@@ -231,10 +231,4 @@ class Migration(migrations.Migration):
231231
options={"proxy": True, "indexes": [], "constraints": []},
232232
bases=("testapp.waitworkflowstate",),
233233
),
234-
migrations.CreateModel(
235-
name="WelcomeWorkflow",
236-
fields=[],
237-
options={"proxy": True, "indexes": [], "constraints": []},
238-
bases=("testapp.welcomeworkflowstate",),
239-
),
240234
]

tests/testapp/models.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from django.conf import settings
22
from django.db import models
33

4+
from joeflow import tasks
45
from joeflow.models import Workflow
56

67

@@ -10,14 +11,40 @@ class Shipment(Workflow):
1011
tracking_code = models.TextField()
1112

1213

13-
class WelcomeWorkflowState(Workflow):
14+
class WelcomeWorkflow(Workflow):
15+
# state
1416
user = models.ForeignKey(
1517
settings.AUTH_USER_MODEL,
1618
on_delete=models.CASCADE,
1719
blank=True,
1820
null=True,
1921
)
2022

23+
# behavior
24+
start = tasks.StartView(fields=["user"])
25+
26+
def has_user(self):
27+
if self.user:
28+
return [self.send_welcome_email]
29+
else:
30+
return [self.end]
31+
32+
def send_welcome_email(self):
33+
self.user.email_user(
34+
subject="Welcome",
35+
message="Hello %s!" % self.user.get_short_name(),
36+
)
37+
38+
def end(self):
39+
pass
40+
41+
edges = [
42+
(start, has_user),
43+
(has_user, end),
44+
(has_user, send_welcome_email),
45+
(send_welcome_email, end),
46+
]
47+
2148

2249
class SimpleWorkflowState(Workflow):
2350
pass

tests/testapp/urls.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from django.contrib import admin
1717
from django.urls import include, path
1818

19-
from . import workflows
19+
from . import models, workflows
2020

2121
urlpatterns = [
2222
path("admin/", admin.site.urls),
@@ -26,5 +26,5 @@
2626
path("gateway/", include(workflows.GatewayWorkflow.urls())),
2727
path("splitjoin/", include(workflows.SplitJoinWorkflow.urls())),
2828
path("loop/", include(workflows.LoopWorkflow.urls())),
29-
path("welcome/", include(workflows.WelcomeWorkflow.urls())),
29+
path("welcome/", include(models.WelcomeWorkflow.urls())),
3030
]

tests/testapp/workflows.py

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -40,35 +40,6 @@ class Meta:
4040
proxy = True
4141

4242

43-
class WelcomeWorkflow(models.WelcomeWorkflowState):
44-
start = tasks.StartView(fields=["user"])
45-
46-
def has_user(self):
47-
if self.user:
48-
return [self.send_welcome_email]
49-
else:
50-
return [self.end]
51-
52-
def send_welcome_email(self):
53-
self.user.email_user(
54-
subject="Welcome",
55-
message="Hello %s!" % self.user.get_short_name(),
56-
)
57-
58-
def end(self):
59-
pass
60-
61-
edges = [
62-
(start, has_user),
63-
(has_user, end),
64-
(has_user, send_welcome_email),
65-
(send_welcome_email, end),
66-
]
67-
68-
class Meta:
69-
proxy = True
70-
71-
7243
class SimpleWorkflow(models.SimpleWorkflowState):
7344
start_view = tasks.StartView(fields="__all__", path="custom/postfix/")
7445
start_method = tasks.Start()

0 commit comments

Comments
 (0)