Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple xwf_models.Workflow #9

Open
ouhouhsami opened this issue Jan 6, 2013 · 4 comments
Open

Multiple xwf_models.Workflow #9

ouhouhsami opened this issue Jan 6, 2013 · 4 comments
Labels

Comments

@ouhouhsami
Copy link

Hello,

Great app ... thanks !

I'm looking for a way to have workflow "instance based". I have multiple instance of my model, say InstA and InstB, and I would like to assign them different workflows, based on, for example instance attribute (for instance the foo boolean field in my example below).
I tried this, but it doesn't work :

class MyModel(xwf_models.WorkflowEnabled, models.Model):

    def __init__(self, *args, **kwargs):
        # try to dynamically set the workflow based on a field for example
        super(MyModel, self).__init__(*args, **kwargs)
        if self.foo is True:  # example of a thing I would like to achieve, to have custom workflow based on instance attribute
            field = xwf_models.StateField(BaseWorkflow2)
            field.contribute_to_class(CustomFormInstance, "state")

    state = xwf_models.StateField(BaseWorkflow)
    foo = models.BooleanField()

Is my problem clear, and do you thing django_xworkflows could face this use case ?

Regards,

@rbarrois
Copy link
Owner

rbarrois commented Jan 7, 2013

Glad you like the app!

You have an interesting problem, which indeed would require lots of hacks to work with the current version of xworkflows (and django_xworkflows).

The main issue I'd see with your approach is the fact that the chosen workflow depends on an instance field ; but XWorkflows uses metaclasses to alter various methods of the class depending of the attached workflow... (this is one of the reasons for your code not working).

A simple example of those issues would be:
What would happen, in your example, if self.foo is suddenly switched to False? Should all transition checks and implementations be modified on the fly, and the state changed to the initial state of the other workflow?

The simplest way I'd see would be to build a single Workflow containing states and transitions from both options, and play with the @check_transition hook to restrict them depending on self.foo.

The only change needed to xworkflows would be to set the initial state based on foo, I could had a method to BaseWorkflowEnabled for that:

class MyObject(WorkflowEnabled):
    def _xworkflow_initial_state(self, field):
        if self.foo:
            return MyWorkflow.states.branch_a
        else:
            return MyWorkflow.states.branch_b

@ouhouhsami
Copy link
Author

Thanks for your answer.

You're absolutely right for the initial state issue. Moreover it could be mandatory to share the same initial state, for all of the instances.

Also, the transitions could be different from an instance to another. Say instA could have ('get_old', 'new', 'old') transition, and instB have ('get_old2', 'new', 'old2') transition, so we should then test if transition belongs entirely to the subsection of states.branch_a or states.branch_b, as you say, using @transition_check.

BTW, if I understand your answer :

  1. First, I should do some work to the metaclass WorkflowEnabledMeta (from xworkflows), adding in the __new__ a ref to _xworkflow_initial_state of my model (https://github.com/rbarrois/xworkflows/blob/master/src/xworkflows/base.py#L1008)
  2. Then I should update the states based on my condition (in our example self.foo, but could be any other condition). But I don't understand where to put my call to the _xworkflow_initial_state, and if it's the right way to do it.
  3. Write some @transition_check to be sure that I apply an available function for the instance I deal with, based on it workflow.

Regards,

@rbarrois
Copy link
Owner

That would be the main idea, yes.

But I think the _xworkflow_initial_state method should be incorporated into xworkflows itself, it's a useful feature for other cases.

Feel free to ping me if you need help on that topic !

@ouhouhsami
Copy link
Author

Hello,

I quickly tried to test the idea of _xworflow_initial_state here ouhouhsami/xworkflows@745193a

Tests pass, but the design is not very clean.
Is the good way would be to have a method on BaseWorkflow to get the initial state from an instance of a BaseWorkflowEnabled through the _xworkflow_initial_state, more or less like log_transition method does inside BaseWorkflow class ?

Also, for my own use case, as long as I have distinct initial states and disjoint transitions, it seems to do the trick, but I have to test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants