[PR] 不動産担保ローン
Python Pylons バリデーションのカスタマイズ
Pylonsのバリデーションのカスタマイズを試してみます。
http://wiki.pylonshq.com/pages/viewpage.action?pageId=11174255
まず、メールアドレスの検証方法を変更してみます。
/controllers/hello.py
#インポートを追加
import formencode
#emailメソッドを変更
def email(self):
schema = EmailForm()
try:
#検証実行
form_result = schema.to_python(request.params)
except formencode.validators.Invalid, error:
return 'Invalid: %s' % error
else:
return 'Your email is: %s' % form_result.get('email_field')
schema.to_pythonというメソッドを実行することで、
データの検証が行われ、不正なデータである場合は
formencode.validators.Invalidが発生するようです。
そして、errorオブジェクトに
#メールアドレスを入力してね
email_field: Please enter an email address
#入力された文字に@がないよ
email_field: An email address must contain a single @
#@の後にドメイン名がないよ
email_field: The domain portion of the email address is invalid (the portion after the @: )
等など、エラーの内容が入っています。
戻り値のform_resultには、検証後きれいになったデータが
入っているので、検証を通過した場合にはform_resultから
データを取り出し、表示しています。
今まで、標準の
formencode.validators.Email
を使ってメールアドレスの検証を行ってきました。
例えば、「このドメインのアドレス以外はエラーにしたい」
という要件があった場合、クラスを継承してルールを追加すると幸せです。
/lib/form.py
にEmailFormクラスを定義していたかと思いますが、これを
カスタムします。
import formencode
#formencode.validators.Emailを継承したクラスを作成
class SimpleEmail(formencode.validators.Email):
#_to_pythonというメソッドを追加
def _to_python(self, value, c):
#引数c(テンプレートエンジンに渡される変数)の
#domeinに指定されている値で終了していなかったら
#エラー発生
if not value.endswith(c.domain):
raise formencode.validators.Invalid('Email addresses must end in: %s' % \
c.domain, value, c)
#Email本来の検証を行う
return formencode.validators.Email._to_python(self, value, c)
#前回作成したクラス
class EmailForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = True
#検証に使用するクラスを上で定義したSimpleEmailに変更
#email_field = formencode.validators.Email(not_empty=True)
email_field = SimpleEmail(not_empty=True)
あわせてコントローラーhello.pyのメソッドを変更
#インポートの追加
import formencode
#HelloControllerクラスのメソッドを変更
def email(self):
schema = EmailForm()
#許可するドメインをし愛知
c.domain = 'example.com'
try:
form_result = schema.to_python(request.params, c)
except formencode.validators.Invalid, error:
return 'Invalid: %s' % error
else:
return 'Your email is: %s' % form_result.get('email_field')
これで、今までのメールアドレスチェックに加え、
example.comドメイン以外のアドレスがエラーに
なるようになりました。
最後に、エラー画面のカスタマイズを行ってみます。
コントローラーhello.pyのemailメソッドをちょっと修正。
def email(self):
schema = EmailForm()
c.domain = 'example.com'
try:
form_result = schema.to_python(request.params, c)
except formencode.validators.Invalid, error:
#return 'Invalid: %s' % error
#テンプレートにエラーの内容を渡す
c.form_result = error.value
c.form_errors = error.error_dict or {}
return render('/form.mako')
else:
return 'Your email is: %s' % form_result.get('email_field')
/templates/form.makoをガッツリ変更
${h.form(h.url(action='email'), method='post')}
% if c.form_errors:
<h2>Please correct the errors</h2>
% else:
<h2>Enter Email Address</h2>
% endif
% if c.form_errors:
Email Address: ${h.text_field('email_field', value=c.form_result['email_field'] or '')}
<p>${c.form_errors['email_field']}</p>
% else:
Email Address: ${h.text_field('email_field')}
% endif
${h.submit('Submit')}
${h.end_form()}
動かしてみるとこんな感じです。
初回アクセス時
未入力エラー
ドメインがexample.comじゃない
検証通過
うーん。バリデータークラスやmakoについても
調べないといけませんね。。。
もどる