2


ウェブアプリケーションページがアプリケーションの各ページで繰り返し定義される必要があるいくつかの基本メソッドと変数を継承するように、base request handlingクラスを定義しようとしています。類似の機能の一種、django preprocessorsのようなもの。Google App Engineで前処理クラスを定義

class BasePage(webapp.RequestHandler): 
    def __init__(self):  
     self.user = users.get_current_user()  
     self.template_values = { 
       'user': self.user,  
       'environ': self, #I don't like the idea of passing the whole environ object to a template 

       ##The below three functions cannot be executed during _init_ because of absence of self.request 
       #'openid_providers': self.openid_providers(), 
       #'logout_url': self.get_logout_url(), 
       #'request': self.get_request(), 
      }   

    ##A sort of similar functionality like render_to_response in django 
    def render_template(self, template_name, values = None, *args, **kwargs): 
     #PATH is the directory containing the templates 
     if values: 
      for value in values: self.template_values[value] = values[value] 
     self.response.out.write(template.render(PATH+template_name, self.template_values, *args, **kwargs))     

    ##Returns request as the name suggests 
    def logout_url(self): 
     return users.create_logout_url(self.request.url) 

    ##Returns request as the name suggests 
    def request(self): 
     return request 

    ##Returns openid login urls   
    def openid_providers(self): 
     #OPENID_POVIDERS is a list of dictionary 
     for p in OPENID_PROVIDERS: 
      p['login_url'] = users.create_login_url(self.request.get('next', '/') , p['name'], p['url']) 
     return OPENID_PROVIDERS 

すべてがself.requestが利用できないように私は、初期化中に、いくつかの変数を渡すことができないことを除いて正常に動作している:これは、他のページが継承する私の基本クラスです。だから私がやった回避策はテンプレート変数として全体の自己変数を渡すことです。

テンプレート変数(request、logout_urlなど)をテンプレートに提供する他の方法はありますか?私は基本的にTemplate Method Pattern

を使用して、私のAppEngineのコードでは、その問題を解決し、基底クラスがどのように見えるまし

答えて

2

class MyBasePage(webapp.RequestHandler): 
    def __init__(self): 
     # common setup/init stuff here, 
     # omitted for this discussion 

    def Setup(self): 
     # request handling setup code needed in both GET/POST methods, like 
     # checking for user login, getting session cookies, etc. 
     # omitted for this discussion 

    def get(self, *args): 
     self.Setup() 
     # call the derived class' 'DoGet' method that actually has 
     # the logic inside it 
     self.DoGet(*args) 

    def post(self, *args): 
     self.Setup() 
     # call the derived class' 'DoPost' method 
     self.DoPost(*args) 

    def DoGet(self, *args): 
     ''' derived classes override this method and 
      put all of their GET logic inside. Base class does nothing.''' 
     pass 

    def DoPost(self, *args): 
     ''' derived classes override this method and 
      put all of their POST logic inside. Base class does nothing.''' 
     pass 

...あなたの派生クラスは、ほとんどがちょうど心配する必要がありますそれらの内臓のDoGet()DoPost()メソッド。

+0

ありがとうございます!私はカスタムクラスを定義し、ベースクラスのポストを定義し、super()を使用していると考えていましたが、このDoPost、DoGetは素晴らしいようです!!私はこれが多くのdjangoの機能を必要としない私の小さなプロジェクトには良いと思う。 – crodjer

+0

@dcrodjer - 優秀! – bgporter

5

initializeメソッドの共通設定をwebapp.RequestHandlerにすると、bgporterよりもはるかに簡単な解決策です。ここでは、リクエストオブジェクトにはDjangoのようなis_ajaxメソッドを追加したい仕事、からの例です:

class BaseHandler(webapp.RequestHandler): 
    def initialize(self, request, response): 
     super(BaseHandler, self).initialize(request, response) 
     # Add a Django-like is_ajax() method to the request object 
     request.is_ajax = lambda: \ 
      request.environ.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest' 

このメソッドはに呼ばれて、ええと、現在のリクエストとレスポンスのオブジェクトと各要求ハンドラを初期化し、前適切なgetまたはpost(または何でも)メソッドが呼び出されます。

+0

+1 - nice;それを考えなかった。 – bgporter

+0

ええ、そういうことをどうやってできるかはあまり明白ではありません。ハンドラが同じことをするのに '__init__'を使わないのはなぜか分かりません。 –

+0

すてきなソリューション@will! – crodjer

関連する問題