Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

formencode Schema add fields dynamically

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...

like image 416
neurino Avatar asked Sep 26 '26 09:09

neurino


1 Answers

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

like image 193
Yohann Avatar answered Sep 28 '26 23:09

Yohann



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!