jinja2

Filed in FormEncode | Jinja | MongoDB Leave a comment

jinja2つかいはじめました。
なにこれすんごい楽。スタックトレースもとれる。
いま作ってるのはこれでいこう。
あたるとおもうんだけどなー。急いでつくろう。

Pylons+Genshi+FillingParser

Filed in FormEncode | Genshi | Pylons Leave a comment

Fillできたー!

以下、自分だけわかればいい的なぐりがき。
下記のソースで、当該ページのフォームにname=”wa”とでもしておけば、そこにwawawaと出るわけでござる。

#ちょとかきなおした。
コントローラに

        defaults={'wa':"wawawa"}
        return render('base.html', defaults= defaults)

こっちはbase.pyあたりでいいかも。render_genshiをwrapするふりして一部書き換えてるだけ。
dist-packagesの中を書き換えるのはかなりアレなので、アプリの中で書いています。

#Wrap render_genshi
def render_genshi(template_name, extra_vars=None, cache_key=None,
                  cache_type=None, cache_expire=None, method='xhtml',defaults=None):
    """Render a template with Genshi

    Accepts the cache options ``cache_key``, ``cache_type``, and
    ``cache_expire`` in addition to method which are passed to Genshi's
    render function.

    """
    # Create a render callable for the cache function
    def render_template():
        # Pull in extra vars if needed
        globs = extra_vars or {}

        # Second, get the globals
        globs.update(pylons_globals())

        # Grab a template reference
        template = globs['app_globals'].genshi_loader.load(template_name)

        #parserがある場合はFillする
        if parser == None:
            return literal(template.generate(**globs).render(method=method,
                                                             encoding=None))
        else:
            parser = FillingParser(defaults)
            src = literal(template.generate(**globs).render(method=method,
                                                             encoding=None))

            parser.feed(src)
            parser.close()
            return parser.text()
#        ここは元のコード
#        return literal(template.generate(**globs).render(method=method,
#                                                         encoding=None))

    return cached_template(template_name, render_template, cache_key=cache_key,
                           cache_type=cache_type, cache_expire=cache_expire,
                           ns_options=('method'), method=method)

Pylons+Genshi+FormEncode(?)でフォームに値をFillしたい。

Filed in FormEncode | Genshi Leave a comment

http://snipplr.com/view/10049/full-formencode–htmlfill-example-with-form-and-test-values/

この分かりやすい例は、完全に働くFormEncode(v1.2)の例をテストして、見せびらかします。 私が、例を見つけるのに苦労したので、現在、それを差し上げます。

のようなことがかいてある。これか?
というかValidatorつかってFillすんのかー?
もはや値をfillできるならどんな手段だってかまわぬ。正しい方法が見つかったら、そこで直せばいいのだし。

追記:
これ普通のバリデーションだった。さっくりrender周辺でfillするにはどうしたらいいのだ。

情報が見つからない。

Filed in FormEncode | Genshi Leave a comment

FormEncodeのFillerについて調べようとしたら、

おねーさんブログが引っかかりました。つまりこれ。
おいwwwwwwwwwwwwwwwwwwwwここ参考にならないことしか書いてないwwwwww
調べものがすすまないよう。

FormEncode:checkboxのValidation

Filed in FormEncode | Pylons | Python Leave a comment

たった数個のチェックボックスに対してのバリデーションに悩んでました。
要求:

  1. 個数は可変
  2. アプリが提供する、いくつかの決まった値とANDである必要がある(想定している正しい値である必要がある)
  3. いづれか一個は選択されていなければならない
  4. いっそ面倒なので値は必ず数字である
  5. エラーチェックは以下のとおり。
  6. 0こチェック状態は認めない
  7. [1,2,3]と想定したなら’4’も’A’も不正

……普通に考えたらきわめて楽勝な条件よね。よくあるでしょこんなの。
少なくともphpなら書くの5分ですよ。
このチェック機構を実装するだけで実に一週間以上悩む羽目になりました。
PythonがアホとかPylonsが云々とかいう理由ではないですが、FormEncodeでのバリデーションをするにあたって、上記の要求がいささか面倒なものだったのかもしれず、あたしには難儀なパズルでした。
いや、よくあるケースだと思うので勘違いだろうとは思うんだ。
「すべての中の最低ひとつでも選択しているか」という条件をどう拾うかというのが壁になりました。
蓋が開いてみれば、大前提への理解の問題だったんですけどね。

以下にトラブルの内容を羅列。
FormEncodeの使用方法で間違っている可能性は大いにあるので、勘違いも含まれているとは思います。

  • Setなどを使わない限りmissingValueで定義されてる例外”Missing value”が表示される。
  • 逆に言うとSetじゃ空でもスルーしてしまって使えない。
  • “Missing value”メッセージがでる条件下では、Validatorにto_python()を記述して各種条件で拾おうとしても状態を取り出せない
  • クラスをさかのぼっていくと、”Missing value”が定義されているのはclass Schema(FancyValidator)。ちょwほとんど一番上w
  • つまりto_python以前にraiseされてて検証ロジックを通せてない?
  • 無条件raiseを書いてみてもやっぱりmissingValue表示。自前Validatorでは引っ掛けるの無理なのか?

で、ふと思いついた解決法を試したところ、あたくしの要件は満たせたので解決いたしました。
きわめてダサい解法。笑ってください。あたしは笑いました。
ダサい解決法を例示する前に、結果的に判明したわりと当然な事実を書いておきます。

  1. 一個もチェックされていない状態のcheckboxは送信されていない
  2. だからmissingValueになる
  3. だから値をとる以前に蹴られていた

ような気がします。これってkeyerrorとかになる気がするんだけど。

「じゃあ絶対に目的のnameのフィールドが送信されるようにすればいいんだな!?」

そういうことでした。

ダサい解決手順:

1.templateに値を仕込む

<label><input type=”checkbox” name=”type_cd” value=”1″/>帆船</label>
<label><input type=”checkbox” name=”type_cd” value=”2″/>複合船(ガレー船)</label>
<input type=”checkbox” name=”type_cd” value=”0″ checked=”checked” style=”visibility:hidden;”/>

このvisibility:hiddenなチェックボックスはhidden tagでも大丈夫。

あたしの場合は、最終的に各チェック済値の合算を取るつもりだったので、0なら未選択と等しい、という解釈が可能でした。
全チェック状態なら0+1+2、未選択なら0、問題ない。そしてもし0ならraise。

2.Validatorを書く。親クラスは何でもいい(たぶんFancyValidatorでいい)。

上の例で行けば、[0, 1, 2]のいずれかを最低一個含み、それ以外の値が送信されていないことを検証するValidatorを書きます。

class DasaiValidate(formencode.validators.FancyValidator):
    #input param
    __unpackargs__ = ('inputlist',)
    def _to_python(self, value, c):
    if len(value) <= 1:
        raise formencode.validators.Invalid(u'どれかひとつは選択してください', value, c)
    for x in value:
        if x not in self.inputlist:
            raise formencode.validators.Invalid(u'不正な値', value, c)

最低限の内容ですがこれで取りこぼしなくいけました。ほんとはもう少し書いてますが。
あとは呼び出し側で、

inputlist = ['0','1','2']
type_cd   = DasaiValidate(inputlist)

こう。inputlistの中身はこちらが許容する値のリスト。必ず送信されることが保障されている’0’がキモ。
ちゃんとしたPythonistaの人たちが見たら殴られそうですが、万が一目をつけられたときに赤ペン先生してもらえるかもという期待をこめてここに恥晒しエントリを残します。

すっごいあきれるくらい簡単な解決方法があるんだろうな、ほんとは。

FormEncodeが便利すぎる件

Filed in FormEncode | Pylons Leave a comment

波浪ノ
おねーさんです。

もはやあたくしにとってクックブック状態にあるfujishinkoさんのページで、FormEncodeの使い方を理解したあたくし、早速つかってみますと。

なんだこれ楽
考えるだけでうんざりだったバリデーションがこんなに簡単に済んじゃうんですか。
という具合で鼻息荒いです。
WAF使う利点というのはこういうとこですよね。

Pylons 0.9.7 で validate エラーメッセージを日本語化

デコレータの使いかたってこういうことなのね。2chでもちょこっとデコレータ関連の書き込みがあって参考になったんですが、使いこなせるか否かでかなり書き方が変わりそう。
languageで指定してやることで各国語のエラーメッセージになると。

# -*- coding: utf-8 -*-
import formencode
formencode.api.set_stdtranslation(domain="FormEncode",languages=["ja"])

class ValidateSignup(formencode.Schema):
    allow_extra_fields = True
    filter_extra_fields = True
    user_name    = formencode.validators.PlainText(min=5,max=20)

TOP