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)
...
我原本以为可以简单地这样做:
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)
因为我在 FormEncode 的文档中看到:
验证器使用实例变量来存储它们的自定义信息。你可以通过子类化或者正常实例化来设置这些。
而且文档中提到 Schema
是一个复合验证器,它是 FancyValidator
的子类,所以我猜这样做是对的。
但是这样并没有成功:我简单添加的 phone_n
被忽略了,只有 name
是必填的。
更新:
我还尝试了重写 __new__
和 __classinit__
,但在提问之前都没有成功……
1 个回答
5
我也遇到过同样的问题,后来在这里找到了解决办法: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))
我觉得没必要调用父类的init。