validationturbogears2formencode

TurboGears 2.3 @validte in two steps


I'm using TurboGears 2.3 and working on validating forms with formencode and need some guidance

I have a form which covers 2 different objects. They are a almost the same, but with some difference When i submit my form, I want to validate 2 things

  1. Some basic data
  2. Some specific data for the specific object

Here are my schemas:

class basicQuestionSchema(Schema):
    questionType = validators.OneOf(['selectQuestion', 'yesNoQuestion', 'amountQuestion'])
    allow_extra_fields = True


class amount_or_yes_no_question_Schema(Schema):
    questionText = validators.NotEmpty()
    product_id_radio = object_exist_by_id(entity=Product, not_empty=True)
    allow_extra_fields = True


class selectQuestionSchema(Schema):
    questionText = validators.NotEmpty()
    product_ids = validators.NotEmpty()
    allow_extra_fields = True

And here are my controller's methods:

@expose()
@validate(validators=basicQuestionSchema(), error_handler=questionEditError)
def saveQuestion(self,**kw):
    type = kw['questionType']
    if type == 'selectQuestion':
        self.save_select_question(**kw)
    else:
        self.save_amount_or_yes_no_question(**kw)


@validate(validators=selectQuestionSchema(),error_handler=questionEditError)
def save_select_question(self,**kw):
    ...
    Do stuff
    ...



@validate(validators=amount_or_yes_no_question_Schema(),error_handler=questionEditError)
def save_amount_or_yes_no_question(self,**kw):
    ...
    Do other stuff
    ...

What I wanted to do was validate twice, with different schemas. This doesn't work, as only the first @validate is validated, and the other are not (maybe ignored)

So, what am i doning wrong?

Thanks for the help


Solution

  • @validate is part of the request flow, so when manually calling a controller it is not executed (it is not a standard python decorator, all TG2 decorators actually only register an hook using tg.hooks so they are bound to request flow).

    What you are trying to achieve should be done during validation phase itself, you can then call save_select_question and save_amount_or_yes_no_question as plain object methods after validation.

    See http://runnable.com/VF_2-W1dWt9_fkPr/conditional-validation-in-turbogears-for-python for a working example of conditional validation.