Last active
August 29, 2015 14:02
-
-
Save blopker/341aad62241f3637bd8d to your computer and use it in GitHub Desktop.
Django Creek API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.views.generic import View | |
from django.http import HttpResponse | |
from django_creek import FlowState, FlowController, flowState | |
class ViewOne(FlowState, View): # Supports CBVs, just mix in a standard Django View or View subclass | |
flow_name = 'one' | |
def get(self, request): | |
return self.render({}) | |
def post(self, request): | |
if request.POST.get('answer') == 'correct': | |
return self.flow.next() # Redirect to next flow | |
# OR go to a specific state in a complex flow | |
return self.flow.next('three') | |
return self.render({'error': 'incorrect'}) | |
def render(self, ctx): | |
return HttpResponse('one ' + str(ctx)) | |
class ViewTwo(FlowState, View): | |
flow_name = 'two' | |
def get(self, request): | |
return self.render({}) | |
def post(self, request): | |
if request.POST.get('answer') == 'correct': | |
return self.flow.next() # Redirect to next flow | |
return self.render({'error': 'incorrect'}) | |
def render(self, ctx): | |
return HttpResponse('two ' + str(ctx)) | |
@flowState('three') | |
def viewThree(request, **kwargs): # Also supports FBVs | |
kwargs['flow'].end() # Erase flow history on the last view if you'd like | |
return HttpResponse('three ' + str({'message': 'end'})) | |
class NumberFlowController(FlowController): | |
# Simple flow, common case. | |
flow = [ViewOne, | |
ViewTwo, | |
viewThree] | |
# OR define a complex flow | |
# Complex flow with valid transitions | |
flow = { | |
ViewOne: (ViewTwo, viewThree), | |
ViewTwo: (viewThree,) | |
} | |
index = ViewOne # Must define initial flow state if flow is complex | |
# Add the flow's URLs to your urlpatterns | |
# Add ?debug=true as a query parameter to any flow state URL to disable redirects. (Only if DEBUG=True) | |
# ?debug=false resets back to normal. | |
urlpatterns = NumberFlowController.urlpatterns() | |
# patterns('', # All URLs go to last completed flow state if the flow state before it is incomplete. | |
# url(r'^$', NumberFlowController.dispatch, name='index'), # Goes to last completed flow state | |
# url(r'one/$', NumberFlowController.dispatch, {'flow': 'one'}, name='one'), | |
# url(r'two/$', NumberFlowController.dispatch, {'flow': 'two'}, name='two'), | |
# url(r'three/$', NumberFlowController.dispatch, {'flow': 'three'}, name='three'), | |
# ) |
If I set up a complex flow like
flow = {
ViewOne: (ViewTwo, viewThree),
ViewTwo: (viewThree, ViewFour)
}
What happens if in ViewOne
I call (assuming I've created ViewFour
with view_name = 'four'
):
return self.flow.next('four')
Does it make more sense to have the controller only know about a single default transitions, not all valid transitions? Otherwise, you can create inconsistencies pretty easily. I'm imagining the "simple" case where the flow is specified with a list works the same, but for the complex flows, you just specify one transition:
flow = {
ViewOne: ViewTwo,
ViewTwo: viewThree,
}
But ViewOne would still be free to go to viewThree if it needed to.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I don't think you should be allowed to define flow states this way. It's much easier to understand if all flow states are defined in the same exact manner. IMO the boilerplate is minimal so we're adding complexity in understanding flows just to be slightly more terse.