我有一个代理网站的flatland表单,如下所示:
class doSomethingForm(Form):
'''Do an action with account credentials'''
username = String.using(default='',
validators=[Present(), UsernameFormat()])
password = String.using(default='',
validators=[Present(), PasswordFormat()])
action = String.using(default='',
validators=[Present(), ActionFormat()])
如果任何参数为空,我希望验证错误是给定元素为空。如果它们非空并满足其他要求,则下一步是询问其他服务是否有效。如果它们无效,那么我想将其转换为验证错误。
这看起来很像flatland的容器级验证,它首先对包含的元素进行验证。所以我尝试了这个:
class doSomethingForm(Form):
'''Do an action with account credentials'''
account = Dict.of(
username = String.named('username').using(default='',
validators=[Present(), UsernameFormat()])
password = String.named('password').using(default='',
validators=[Present(), PasswordFormat()])
).using(validators=[CheckCredentials()])
action = String.using(default='',
validators=[Present(), ActionFormat()])
这看起来会起作用,但现在表单正在寻找名为account_username
和account_password
的元素,这不是我希望的接口。
我看到了几个解决方案:
CheckCredentials
验证程序附加到doSomethingForm
。但是,我没有在文档中看到这样做的方法。CheckCredentials
验证程序附加到username
,access its sibling password
。但是,如果用户名和密码格式不正确,我不想打扰其他服务器。所以我必须首先在username
和password
上运行验证,这似乎重复了我自己。Dict
的一个没有命名空间有没有正确的方法在flatland中添加表单级验证器?
答案 0 :(得分:1)
在阅读了一些文档后,我认为你可以简单地做your_form.validate()
。
Form
类继承Dict
类,因此验证方式与容器级验证通常的工作方式相同。
免责声明:直到你的问题,我从未听说过“平地”,所以我真的可以离开这里。
答案 1 :(得分:1)
检查flatland代码(hg clone http://bitbucket.org/jek/flatland
)非常有用,因为文档和示例还不完整。
Form
继承自Dict
,继承自Container
,继承自Element
。有两个类元素可以提供帮助:
descent_validators
(来自Container
) - 一个可以在下降(第一)阶段运行的可验证器的迭代。 validators
(来自Element
) - 可在上升(第二)阶段运行的可验证器的迭代。要获得我想要的行为(仅在用户名和密码有效时检查帐户),我需要将验证器添加到validators
类变量,并检查子验证器是否已通过。
我的代码现在看起来像这样:
class CheckCredentials(Validator):
'''Checks credentials and creates an account object'''
def validate(self, element, state):
username = element['username']
password = element['password']
if not (username.all_valid and password.all_valid):
return false
self.account = Account(username.u, password.u)
return self.account.valid()
class doSomethingForm(Form):
'''Do an action with account credentials'''
username = String.using(default='',
validators=[Present(), UsernameFormat()])
password = String.using(default='',
validators=[Present(), PasswordFormat()])
action = String.using(default='',
validators=[Present(), ActionFormat()])
validators = (CheckCredentials(),)
@expose('/do_something')
def doSomething(request):
form = doSomethingForm.from_defaults()
form.set_flat(request.form)
result_html = ''
method = request.method
if method == 'POST' and not form.validate():
method = 'GET'
errors = []
if form.errors: errors.extend(form.errors)
for el in form.all_children:
if el.errors: errors.extend(el.errors)
result_html = errorsToHtml(errors)
if method == 'POST':
result_html = form.account.action(form['action'].u)
return render_template('do_something.html',
result=result_html, **form.value)
我认为flatland可以做一些更酷的事情来帮助生成HTML表单,但到目前为止我对此非常满意。