Pylons FormEncode 带有表单元素数组

发布于 2024-07-23 11:23:26 字数 2139 浏览 6 评论 0原文

我有一个 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>

但是,我似乎不知道如何验证这些字段。 中的相关条目

这是我的架构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())

I have a Pylons app and am using FormEncode and HtmlFill to handle my forms. I have an array of text fields in my template (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>

However, I can't seem to figure out how to validate these fields.
Here is the relevant entry from my Schema

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

I'm trying to validate that each of these fields is an Int.
However, no validation occurs for these fields.

UPDATE
As requested here is the code for the action of this controller. I know it was working as I can validate other form fields.

    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')

UPDATE
It was suggested on IRC that I change the name of the elements from yardage[] to yardage
No result. They should all be ints but putting in f into one of the elements doesn't cause it to be invalid. As I said before, I am able to validate other form fields. Below is my entire schema.

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())

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

事实证明我想做的事情不太对。

模板:(

<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把它变成一本字典。 这是在

Schema 中完成的:

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 操作

以下是我的Controller

@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 非常重要,否则字典将无法正确创建。

Turns out what I wanted to do wasn't quite right.

Template:

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

(Should have made it in a loop to begin with.) You'll notice that the name of the first element will become hole-1.yardage. I will then use FormEncode.variabledecode to turn this into a dictionary. This is done in the

Schema:

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())

The HoleSchema will validate that hole-#.par and hole-#.yardage are both ints and are not empty. formencode.ForEach allows me to apply HoleSchema to the dictionary that I get from passing variable_decode=True to the @validate decorator.

Here is the submit action from my

Controller:

@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!'

Using the @validate decorator allows for a much cleaner way to validate and fill in the forms. The variable_decode=True is very important or the dictionary will not be properly created.

你的呼吸 2024-07-30 11:23:26
c.form_result = schema.to_python(request.params) - (without dict)

看起来效果很好。

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

It seems to works fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文