Django-fsm : Dynamic Targets fail due to extra method parameters

594 Views Asked by At

https://github.com/kmmbvnr/django-fsm#target Original example in docs:

@transition(
    field=state,
    source='for_moderators',
    target=GET_STATE(
        lambda self, allowed: 'published' if allowed else 'rejected',
        states=['published', 'rejected']))
def moderate(self, allowed):
    self.allowed=allowed

I'm using the above approach to resolve dynamic target states. My function looks like this:

@fsm_log_by
@transition(
    field=state,
    source=[constants.BookingState.on_hold],
    target=GET_STATE(
        lambda self: constants.BookingState.camop_assigned if self.camera_operator else constants.BookingState.active,
        states=[constants.BookingState.active, constants.BookingState.camop_assigned]),
    permission=can_make_active,
)
def make_active(self, by=None):
    async('some async task', self.pk)
    async('some other async task', self.pk)

I have an additional by=None which is used for logging purposes. However, when I run this function, it says:

<lambda>() got an unexpected keyword argument 'by'

I don't understand why lambda is considering the parameter which I have not even declared in the lambda. I can run it if I remove by=None from the make_active function but I cannot do that as it is an important parameter.

Please help.

1

There are 1 best solutions below

0
saran3h On BEST ANSWER

I figured out what was wrong. lambda automatically takes all the parameters of the method. by=None is of type dictionary so I had to specify **kwargs in lambda.

Updated Code:

@fsm_log_by
@transition(
    field=state,
    source=[constants.BookingState.on_hold],
    target=GET_STATE(
        lambda self, **kwargs: constants.BookingState.camop_assigned if self.camera_operator else constants.BookingState.active,
        states=[constants.BookingState.active, constants.BookingState.camop_assigned]),
    permission=can_make_active,
)
def make_active(self, by=None):
    async('some async task', self.pk)
    async('some other async task', self.pk)