doGet、doPost
Pageクラスにごにょごにょする時にどこにロジックをかけばいいかよくわからんってことになるので明示的に実装
させるところを決めてみる。
はじめてzope.interface使ったよ。
しびれる〜。
import random from time import time as now import twisted.python.components as tpc from twisted.python.components import registerAdapter from nevow import rend from nevow import inevow from nevow import util from zope.interface import implements from zope.interface import Interface class IFlash(Interface): pass class BasePage(rend.Page): def __init__(self, *args, **kwargs): self.callback_args = args self.callback_kwargs = kwargs def locateChild(self, ctx, segments): request = inevow.IRequest(ctx) method = request.method if method == 'POST': method = getattr(self, 'onPost', None) return self.doProcessPost(ctx, method, '') return super(BasePage, self).locateChild(ctx, segments) def beforeRender(self, ctx): request = inevow.IRequest(ctx) method = request.method if method == 'GET': f = getattr(self, 'onGet', None) if f: self.onGet(ctx, *self.callback_args, **self.callback_kwargs) def doProcessPost(self, ctx, method, bindingName): def redirectAfterPost(aspects): hand = aspects.get(inevow.IHand) refpath = request.getHeader('referer') or '' if hand: if isinstance(hand, rend.Page): print hand elif isinstance(hand, basestring): refpath = hand from nevow import url refpath = url.URL.fromString(refpath) magicCookie = '%s%s%s' % (now(),request.getClientIP(),random.random()) refpath = refpath.replace('_nevow_carryover_', magicCookie) rend._CARRYOVER[magicCookie] = C = tpc.Componentized() for k, v in aspects.iteritems(): print k, v C.setComponent(k, v) print "redirect path %s" % str(refpath) request.redirect(str(refpath)) from nevow import static return static.Data('You posted a form to %s' % bindingName, 'text/plain'), () request = inevow.IRequest(ctx) return util.maybeDeferred(method, ctx, *self.callback_args, **self.callback_kwargs ).addCallback(self.onPostSuccess, request, ctx, bindingName,redirectAfterPost ).addErrback(self.onPostFailure, request, ctx, bindingName,redirectAfterPost) def onPostSuccess(self, result, request, ctx, bindingName, redirectAfterPost): if result is None: message = "%s success." % formless.nameToLabel(bindingName) else: message = result flash = {} try: flash = IFlash(ctx) except: pass return redirectAfterPost({inevow.IHand: result, inevow.IStatusMessage: message, IFlash: flash}) def setFlash(self, ctx, obj): ctx.remember(obj, IFlash) def getFlash(self, ctx): obj = None try: obj = IFlash(ctx) except: pass return obj def flashFactory(ctx): co = rend._CARRYOVER.get( ctx.tag.args.get('_nevow_carryover_', [None])[0], None) return IFlash(co, None) registerAdapter(util._namedAnyWithBuiltinTranslation('form.flashFactory'), util._namedAnyWithBuiltinTranslation('nevow.context.RequestContext'), util._namedAnyWithBuiltinTranslation('form.IFlash'))
GETでアクセスされた場合はdoGet、POSTの時はdoPostが呼ばれる。
resolverを使ってるとurlでマッチングした値が引き数に入ってくる。
Flashは特に何もしてない。好きなオブジェクトを突っ込むだけ。
基本的にはPRGパターンを想定してるのでこんな実装になっている。
サンプルはこんな感じ。
class SimplePage(form.BasePage): #addSlash=True docFactory=loaders.xmlfile(util.sibpath(__file__, 'templates/sample.html')) def onGet(self, ctx, id): print "GGGGGGGGGGGGGGGGGGGGGET %s" % id a = self.getFlash(ctx) print a def onPost(self, ctx, id): print "PPPPPPPPPPPPPPPPPPPPOST %s" % id self.setFlash(ctx, "TEST") return "/index/45/"
うくく。