formencode Schema add fields dynamically

1.1k views Asked by At

Let's take, for example, a User Schema where the site admin sets the number of requested phone numbers:

class MySchema(Schema):
    name = validators.String(not_empty=True)
    phone_1 = validators.PhoneNumber(not_empty=True)
    phone_2 = validators.PhoneNumber(not_empty=True)
    phone_3 = validators.PhoneNumber(not_empty=True)
    ...

Somehow I thought I could simply do:

class MySchema(Schema):
    name = validators.String(not_empty=True)
    def __init__(self, *args, **kwargs):
        requested_phone_numbers = Session.query(...).scalar()
        for n in xrange(requested_phone_numbers):
            key = 'phone_{0}'.format(n)
            kwargs[key] = validators.PhoneNumber(not_empty=True)
        Schema.__init__(self, *args, **kwargs)

since I read in FormEncode docs:

Validators use instance variables to store their customization information. You can use either subclassing or normal instantiation to set these.

and Schema is called in docs as a Compound Validator and is a subclass of FancyValidator so I guessed it's correct.

But this does not work: simply added phone_n are ignored and only name is required.

Update:

Also I tried both overriding __new__ and __classinit__ before asking with no success...

1

There are 1 answers

1
Yohann On

i had the same problem, i found a solution here: http://markmail.org/message/m5ckyaml36eg2w3m

all the thing is to use the add_field method of schema in youre init method

class MySchema(Schema):
    name = validators.String(not_empty=True)

    def __init__(self, *args, **kwargs):
        requested_phone_numbers = Session.query(...).scalar()
        for n in xrange(requested_phone_numbers):
            key = 'phone_{0}'.format(n)
            self.add_field(key, validators.PhoneNumber(not_empty=True))

i don't think there's a need to call the parent init