2

私は Pylons アプリを持っており、フォームを処理するために FormEncode と HtmlFill を使用しています。テンプレートにテキスト フィールドの配列があります (Mako)

  <tr>
    <td>ヤーデージ</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 であることを検証しようとしています。ただし、これらのフィールドの検証は行われません。

更新 ここで要求されているのは、このコントローラーのアクションのコードです。他のフォームフィールドを検証できるので、機能していたことはわかっています。

    デフ提出(自己):
        スキーマ = CourseForm()
        試す:
            c.form_result = schema.to_python(dict(request.params))
        formencode.Invalid 以外、エラー:
            c.form_result = error.value
            c.form_errors = error.error_dict または {}
            c.heading = 'コースを追加'
            html = render('/派生/コース/add.html')
            return htmlfill.render(
                html、
                デフォルト = c.form_result、
                エラー = c.form_errors
                )
        そうしないと:
            h.redirect_to(controler='course', action='view')

更新 IRC で、要素の名前をyardage[]からyardage No result に変更するよう提案されました。それらはすべて int でなければなりませんが、要素の 1 つに f を入れても無効にはなりません。前に言ったように、他のフォーム フィールドを検証できます。以下は私のスキーマ全体です。

formencode のインポート

クラス CourseForm(formencode.Schema):
    allow_extra_fields = True
    filter_extra_fields = 真
    name = formencode.validators.NotEmpty(messages={'empty': 'Name must not be empty'})
    par = formencode.ForEach(formencode.validators.Int())
    ヤード数 = formencode.ForEach(formencode.validators.Int())
4

2 に答える 2

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.yardageFormEncode.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が両方とも int であり、空でないことを検証します。デコレータに渡して取得した辞書formencode.ForEachに適用できます。HoleSchemavariable_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は非常に重要です。そうしないと、辞書が適切に作成されません。

于 2009-06-16T23:56:40.150 に答える
1
c.form_result = schema.to_python(request.params) - (without dict)

それはうまくいくようです。

于 2010-10-26T15:26:00.733 に答える