質問

私は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検索結果はありません。それらはすべてINTである必要がありますが、要素の1つに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())
役に立ちましたか?

解決

私がやりたかったことはまったく正しくなかったことがわかりました。

テンプレート:

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

ホレシマはそれを検証します hole-#.parhole-#.yardage どちらもINTであり、空ではありません。 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 非常に重要です。そうしないと、辞書が適切に作成されません。

他のヒント

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

うまく機能しているようです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top