formencode Schema动态添加字段

neu*_*ino 4 python forms formencode

例如,让我们Schema以网站管理员设置所请求电话号码数量的用户为例:

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)
    ...
Run Code Online (Sandbox Code Playgroud)

不知怎的,我以为我可以做到:

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)
Run Code Online (Sandbox Code Playgroud)

自从我在FormEncode文档读到:

验证器使用实例变量来存储其自定义信息.您可以使用子类化或普通实例化来设置它们.

Schema在docs中作为复合验证器调用,并且是一个子类,FancyValidator所以我猜它是正确的.

但是这不起作用:简单地添加phone_n被忽略并且仅name是必需的.

更新:

我也尝试了覆盖__new__,__classinit__然后在没有成功的问题之前......

Yoh*_*ann 6

我有同样的问题,我在这里找到了一个解决方案:http: //markmail.org/message/m5ckyaml36eg2w3m

所有的事情都是在你的init方法中使用schema的add_field 方法

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))
Run Code Online (Sandbox Code Playgroud)

我认为不需要调用父init