当我使用WTForms定义表单时,我可以向子类添加validate_<field name>
方法,WTForms知道使用它来验证命名字段。我发现这很有趣,因为方法的名称取决于字段类属性的名称。它如何解决这个问题?
class UploadForm(Form):
image = FileField("image file")
submit = SubmitField("Submit")
def validate_image(self,field):
if field.data.filename[-4:].lower() != ".jpg":
raise ValidationError("nope not allowed")
答案 0 :(得分:3)
WTForms在调用它时检查类(调用类创建一个实例:form = Form()
)并记录字段及其名称。然后在验证期间,它会查看实例是否有方法validate_<field_name>
。
在FormMeta.__call__
内,它使用dir
函数列出在类对象上定义的名称并记录字段。
for name in dir(cls): # look at the names on the class
if not name.startswith('_'): # ignore names with leading _
unbound_field = getattr(cls, name) # get the value
if hasattr(unbound_field, '_formfield'): # make sure it's a field
fields.append((name, unbound_field)) # record it
在Form.validate
内,它使用getattr
函数尝试为其记录的每个字段获取名称validate_<field name>
的值。
for name in self._fields: # go through recorded field names
# get method with name validate_<field name> or None
inline = getattr(self.__class__, 'validate_%s' % name, None)
if inline is not None: # if there is such a method record it
extra[name] = [inline]
答案 1 :(得分:1)
所有Python类型的所有成员实际上都是哈希表(dict
s),并且所有类型信息都在运行时生成。所以你可以从代码中检查任何Python类。
作为一个快速互动的例子:
>>> class Foo(object):
... my_attribute = 'Something'
...
>>> dir(Foo)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'my_attribute']
>>> Foo.__dict__
dict_proxy({'__dict__': <attribute '__dict__' of 'Foo' objects>, '__module__': '__main__', 'my_attribute': 'Something', '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None})
>>> [x for x in Foo.__dict__ if not x.startswith('__')]
['my_attribute']
>>>