如何向Flatland窗体类添加窗体级别验证?

2024-05-23 15:25:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个代理网站的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的容器级验证,它首先对包含的元素运行验证。所以我试了一下:

^{pr2}$

这看起来是可以工作的,但是现在表单正在寻找名为account_username和{}的元素,这并不是我所希望的接口。在

我看到了几个解决方案:

  1. {cd4{I>可以连接到
  2. 我可以将CheckCredentials验证器附加到username,它可以access its sibling ^{}。但是,如果用户名和密码格式不正确,我不想打扰其他服务器。所以我必须先对username和{}运行验证,这看起来像是在重复我自己。在
  3. 我可以破解一段Dict的一段话,它不做名称空间

有没有正确的方法可以在flatland中添加表单级验证器?在


Tags: default元素表单代理string网站错误username
2条回答

在阅读了一些文档之后,我假设您可以简单地执行your_form.validate()。在

Form类继承了Dict类,因此验证的方式与容器级验证的正常工作方式相同。在

免责声明:在你的问题之前,我从未听说过“平地”,所以我可以离开这里。在

签出flatland代码(hg clone http://bitbucket.org/jek/flatland)是很有用的,因为文档和示例还没有完全到位。在

FormDict继承,后者从Container继承,后者从{}继承。有两个类元素可以帮助:

  • descent_validators(fromContainer)-在下降(第一)阶段运行的一个iterable验证器。在
  • validators(fromElement)-在上升(第二)阶段运行的一个iterable验证器。在

为了获得我想要的行为(仅当用户名和密码有效时才检查account),我需要将我的验证器添加到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表单,但是到目前为止,我对此非常满意。在

感谢WoLpH和{a2}的帮助。在

相关问题 更多 >