3

私がやろうとしていることのベースとして、Nick Johnson の Webapp & Templatesアプリケーションを使用しています。render_template を呼び出そうとすると、「AttributeError: 'NoneType' object has no attribute 'write'」というメッセージが表示されます。オブジェクト「Capture」をXとしてインスタンス化すると、応答プロパティがないためです。解決策を見つけるためにあらゆる場所を探しましたが、どこにも見つかりません。

注: これを行う方法は他にもありますが、セットアップ方法と同じように動作する必要があります!

トレースバック:

Traceback (most recent call last):
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1535, in __call__
    rv = self.handle_exception(request, response, e)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1529, in __call__
    rv = self.router.dispatch(request, response)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "/Users/userx/Documents/_FRESHCUTZ MEDIA/Google/GAE - Test web form 1 /testwebform1/main.py", line 41, in post
    x.calculateYear(name, age)
  File "/Users/userx/Documents/_FRESHCUTZ MEDIA/Google/GAE - Test web form 1 /testwebform1/main.py", line 49, in calculateYear
    self.response.write(self.render_template('index.html', **template_args))
AttributeError: 'NoneType' object has no attribute 'write'

メイン.PY

import os
import webapp2
from webapp2_extras import jinja2

class BaseHandler(webapp2.RequestHandler):
  @webapp2.cached_property
  def jinja2(self):
        return jinja2.get_jinja2(app=self.app)

  def render_template(self, filename, **template_args):
        self.response.write(self.jinja2.render_template(filename, **template_args))

class MainPage(BaseHandler):
  def get(self):
    template_args = {}
    self.render_template('index.html', **template_args)

class CaptureDetails(BaseHandler):
  def post(self):
    name = self.request.get("name").strip()
    age = self.request.get("age").strip()

    x = Calculate()
    x.calculateYear(name, age)

class Calculate(BaseHandler):
    def calculateYear(self, name, age):
       template_args = {"age": age} 
       self.render_template('name.html', **template_args) 

app = webapp2.WSGIApplication([
      ('/', MainPage),
      ('/capture', CaptureDetails),
      ('/age', Calculate)
    ], debug=True)

私は何を間違っていますか?どんな助け/提案も大歓迎です!

4

3 に答える 3

2

クラスcalculateYearの関数を作成する場合(または、より適切な場合は他の場所)、それはあなたの基準に適合しますか? BaseHandlerご想像のとおり、あなたxは適切なとして扱われていませんresponse。ハンドラーを呼び出すwebapp2.RequestHandlerと、リクエストのタイプに関連付けられたメソッドが呼び出されます (この場合、フォームを投稿しているため、post()ご存知のように が呼び出されます)。をインスタンス化xして呼び出すcalculateYear場合、特定のメソッド ( 、 など) を指定していないdef get(self)ためdef post(self)、 の準備はありませんresponse(機会があれば、これが実際に当てはまることを確認するために少し掘り下げます - 私は間違っている可能性があります:))。

これを今すぐテストすることはできませんが、ハンドラーcalculateYear以外から呼び出す必要があると仮定すると、これは機能しますか? CaptureDetailsここでselfは、メソッドのコンテキストで参照し、処理postを呼び出します。response

class BaseHandler(webapp2.RequestHandler):
  @webapp2.cached_property
  def jinja2(self):
      return jinja2.get_jinja2(app=self.app)

  def render_template(self, filename, **template_args):
      self.response.write(self.jinja2.render_template(filename, **template_args))

  def calculateYear(self, name, age):
      template_args = {"age": age} 
      self.render_template('name.html', **template_args)

CaptureDetails次に、ハンドラーから次のように呼び出すことができます。

class CaptureDetails(BaseHandler):
  def post(self):
    name = self.request.get("name").strip()
    age = self.request.get("age").strip()

    # Call the function and write the response
    self.calculateYear(name, age)
于 2012-12-14T20:00:54.133 に答える
1

Calculateメソッドで自分自身をインスタンス化CaptureDetails.postすることにより、同じ方法で作成していないWSGIApplicationため、プロパティは使用できません。具体的には、 aresponseを渡していないので、当然のことながら、それを参照しようとしてもうまくいきません。

この場合、calculateYearpost メソッドに の内容をコピーします。インスタンスを作成してそのメソッドを呼び出さなければならないので、実際には何も節約できません。calculateYearより複雑になり、重複を望まない場合は、両方のハンドラー メソッドから呼び出すことができる新しいメソッドを紹介します。(この例からは、Calculateクラスが存在する理由は明確ではありません。「get」メソッドがないため、行ったようにマッピングしても機能し/ageません。)

于 2012-12-14T20:02:23.413 に答える
0

self.response.out.writeの代わりに使ってみてくださいself.response.write

于 2012-12-14T19:36:13.517 に答える