Pylons FormEncode包含一系列表单元素

时间:2009-06-15 04:04:25

标签: python pylons formencode htmlfill

我有一个Pylons应用程序,并使用FormEncode和HtmlFill来处理我的表单。我的模板(Mako)中有一系列文本字段

  <tr>
    <td>Yardage</td>
    <td>${h.text('yardage[]', maxlength=3, size=3)}</td>
    <td>${h.text('yardage[]', maxlength=3, size=3)}</td>
    <td>${h.text('yardage[]', maxlength=3, size=3)}</td>
    <td>${h.text('yardage[]', maxlength=3, size=3)}</td>
    <td>${h.text('yardage[]', maxlength=3, size=3)}</td>
    <td>${h.text('yardage[]', maxlength=3, size=3)}</td>
    <td>${h.text('yardage[]', maxlength=3, size=3)}</td>
    <td>${h.text('yardage[]', maxlength=3, size=3)}</td>
    <td>${h.text('yardage[]', maxlength=3, size=3)}</td>
  </tr>

但是,我似乎无法弄清楚如何验证这些字段。 以下是我的Schema的相关条目

yardage = formencode.ForEach(formencode.validators.Int())

我正在尝试验证每个字段都是Int。 但是,这些字段不会进行验证。

更新 这里要求的是该控制器动作的代码。我知道它正在工作,因为我可以验证其他表单字段。

    def submit(self):
        schema = CourseForm()
        try:
            c.form_result = schema.to_python(dict(request.params))
        except formencode.Invalid, error:
            c.form_result = error.value
            c.form_errors = error.error_dict or {}
            c.heading = 'Add a course'
            html = render('/derived/course/add.html')
            return htmlfill.render(
                html,
                defaults = c.form_result,
                errors = c.form_errors 
                )
        else:
            h.redirect_to(controler='course', action='view')

更新 在IRC上建议我将元素的名称从yardage[]更改为yardage 没有结果。它们都应该是整数,但是将f放入其中一个元素并不会导致它无效。正如我之前所说,我能够验证其他表单字段。以下是我的整个架构。

import formencode

class CourseForm(formencode.Schema):
    allow_extra_fields = True
    filter_extra_fields = True
    name = formencode.validators.NotEmpty(messages={'empty': 'Name must not be empty'})
    par = formencode.ForEach(formencode.validators.Int())
    yardage = formencode.ForEach(formencode.validators.Int())

2 个答案:

答案 0 :(得分:5)

原来我想做的事情不太对劲。

<强>模板

<tr>
  <td>Yardage</td>
  % for hole in range(9):
  <td>${h.text('hole-%s.yardage'%(hole), maxlength=3, size=3)}</td>
  % endfor
</tr>

(应该以循环方式开始。)您会注意到第一个元素的名称将变为hole-1.yardage。然后我将使用FormEncode.variabledecode将其转换为字典。这是在

中完成的

<强>模式

import formencode

class HoleSchema(formencode.Schema):
    allow_extra_fields = False
    yardage = formencode.validators.Int(not_empty=True)
    par = formencode.validators.Int(not_empty=True)

class CourseForm(formencode.Schema):
    allow_extra_fields = True
    filter_extra_fields = True
    name = formencode.validators.NotEmpty(messages={'empty': 'Name must not be empty'})
    hole = formencode.ForEach(HoleSchema())

HoleSchema将验证hole-#.parhole-#.yardage是否为整数且不为空。 formencode.ForEach允许我将HoleSchema应用于通过variable_decode=True传递给@validate装饰器的词典。

以下是我

submit操作

<强>控制器

@validate(schema=CourseForm(), form='add', post_only=False, on_get=True, 
          auto_error_formatter=custom_formatter,
          variable_decode=True)
def submit(self):
    # Do whatever here.
    return 'Submitted!'

使用@validate装饰器可以更清晰地验证和填写表单。 variable_decode=True非常重要,或者无法正确创建字典。

答案 1 :(得分:1)

c.form_result = schema.to_python(request.params) - (without dict)

似乎工作正常。