第 9 章 アプリケーションのデプロイ 49
14.3 実習 データの保存
Todoフォームから送信されたデータを保存できるようにしましょう。
80 第14章 データストアを使う
14.3.1 実習の手順
実習の手順はおおむね次のようになります 1. ToDoクラスを定義する
2. ToDoオブジェクトをデータストアに保存する
3. 保存完了後の処理を追加する
手順1. ToDoクラスを定義する
1 from google.appengine.ext import ndb
2
3 # ...略...
4
5 class Todo(ndb.Model):
6 author = ndb.UserProperty()
7 content = ndb.StringProperty(indexed=False)
8 date = ndb.DateTimeProperty(auto_now_add=True)
手順2. ToDoオブジェクトをデータストアに保存する postメソッドを次の処理を実装します。
1. 前章で追加した、送信データを表示するコードは削除する 2. Userのログイン判定処理を追加する
14.3. 実習 データの保存 81
また、登録されたデータはDetastoreViewerから確認することができます。
DetastoreViewerはLauncherから[SDK Console]を、クリックするとブラウザが起動します。左のメニューから [DatastoreViewer]をクリックします。
14.3 実習 データの保存
Todoフォームから送信されたデータを保存できるようにしましょう。
80 第14章 データストアを使う
14.3.1 実習の手順
実習の手順はおおむね次のようになります 1. ToDoクラスを定義する
2. ToDoオブジェクトをデータストアに保存する
3. 保存完了後の処理を追加する
手順1. ToDoクラスを定義する
1 from google.appengine.ext import ndb
2
3 # ...略...
4
5 class Todo(ndb.Model):
6 author = ndb.UserProperty()
7 content = ndb.StringProperty(indexed=False)
8 date = ndb.DateTimeProperty(auto_now_add=True)
手順2. ToDoオブジェクトをデータストアに保存する postメソッドを次の処理を実装します。
1. 前章で追加した、送信データを表示するコードは削除する 2. Userのログイン判定処理を追加する
14.3. 実習 データの保存 81
3. ToDoオブジェクトを生成し、プロパティの値を設定する
• authorプロパティ: Userオブジェクトのnickname
• content: postのパラメータcontentをhtmlエスケープした値
1 class MainHandler(webapp2.RequestHandler):
2 def get(self):
3 # ...略...
4
5 def post(self):
6 # 以下のコードはコメントアウトまたは削除する
7 # content = cgi.escape(self.request.get('content'))
8 # self.response.write('New Todo:' + content)
9
10 # Userのログイン判定処理を追加する
11 user = users.get_current_user()
12 if user is None:
13 self.redirect(users.create_login_url(self.request.uri))
14 return
15
16 # ToDoオブジェクトを生成し、プロパティの値を設定する
17 todo = Todo()
18 todo.content = cgi.escape(self.request.get('content'))
19
20 # ToDoオブジェクトをデータストアに保存する
21 key = todo.put()
手順3. 保存完了後の処理を追加する
データの保存が完了したら、次の処理を追加します。
1. 保存データのKeyオブジェクトをログに出力します。
2. メインページに遷移します
• self.redirect(’/’)で、メインページにリダイレクトしています。
1 class MainHandler(webapp2.RequestHandler):
2 def get(self):
3 # ...略...
4
5 def post(self):
6 # ...略...
7
8 logging.info("key=%s" % str(key))
9 self.redirect('/')
82 第14章 データストアを使う
main.py
main.pyは次のような内容になります。
1 # coding: utf-8
-*-2 #!/usr/bin/env python
3 #
4 # Copyright 2007 Google Inc.
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 #
18 from google.appengine.api import users
19 from google.appengine.ext import ndb
20 import cgi
21 import os
22 import jinja2
23 import webapp2
24 import logging
25
26 JINJA_ENVIRONMENT = jinja2.Environment(
27 loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
28 extensions=['jinja2.ext.autoescape'],
29 autoescape=True)
30 31
32 class Todo(ndb.Model):
33 """Models an individual Todo entry with author, content, and date."""
34 author = ndb.UserProperty()
35 content = ndb.StringProperty(indexed=False)
36 date = ndb.DateTimeProperty(auto_now_add=True)
37 38
39 class MainHandler(webapp2.RequestHandler):
40 def get(self):
41 self.response.write('<html><body>')
42 self.response.write('<h1>TODOリスト</h1>')
43 self.response.write('<form method="post" action="/">')
14.3. 実習 データの保存 83
3. ToDoオブジェクトを生成し、プロパティの値を設定する
• authorプロパティ: Userオブジェクトのnickname
• content: postのパラメータcontentをhtmlエスケープした値
1 class MainHandler(webapp2.RequestHandler):
2 def get(self):
3 # ...略...
4
5 def post(self):
6 # 以下のコードはコメントアウトまたは削除する
7 # content = cgi.escape(self.request.get('content'))
8 # self.response.write('New Todo:' + content)
9
10 # Userのログイン判定処理を追加する
11 user = users.get_current_user()
12 if user is None:
13 self.redirect(users.create_login_url(self.request.uri))
14 return
15
16 # ToDoオブジェクトを生成し、プロパティの値を設定する
17 todo = Todo()
18 todo.content = cgi.escape(self.request.get('content'))
19
20 # ToDoオブジェクトをデータストアに保存する
21 key = todo.put()
手順3. 保存完了後の処理を追加する
データの保存が完了したら、次の処理を追加します。
1. 保存データのKeyオブジェクトをログに出力します。
2. メインページに遷移します
• self.redirect(’/’)で、メインページにリダイレクトしています。
1 class MainHandler(webapp2.RequestHandler):
2 def get(self):
3 # ...略...
4
5 def post(self):
6 # ...略...
7
8 logging.info("key=%s" % str(key))
9 self.redirect('/')
82 第14章 データストアを使う
main.py
main.pyは次のような内容になります。
1 # coding: utf-8
-*-2 #!/usr/bin/env python
3 #
4 # Copyright 2007 Google Inc.
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 #
18 from google.appengine.api import users
19 from google.appengine.ext import ndb
20 import cgi
21 import os
22 import jinja2
23 import webapp2
24 import logging
25
26 JINJA_ENVIRONMENT = jinja2.Environment(
27 loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
28 extensions=['jinja2.ext.autoescape'],
29 autoescape=True)
30 31
32 class Todo(ndb.Model):
33 """Models an individual Todo entry with author, content, and date."""
34 author = ndb.UserProperty()
35 content = ndb.StringProperty(indexed=False)
36 date = ndb.DateTimeProperty(auto_now_add=True)
37 38
39 class MainHandler(webapp2.RequestHandler):
40 def get(self):
41 self.response.write('<html><body>')
42 self.response.write('<h1>TODOリスト</h1>')
43 self.response.write('<form method="post" action="/">')
14.3. 実習 データの保存 83
44 self.response.write('<input type="text" name="content">')
45 self.response.write('<input type="submit" value="送信" />')
46 self.response.write('</form>')
47 self.response.write('</body></html>')
48
49 def post(self):
50 user = users.get_current_user()
51 if user is None:
52 self.redirect(users.create_login_url(self.request.uri))
53
54 todo = Todo()
55 todo.content = cgi.escape(self.request.get('content'))
56 todo.author = user.nickname()
57 key = todo.put()
58 logging.info("key=%s" % str(key))
59 self.redirect('/')
60 61
62 class MyPageHandler(webapp2.RequestHandler):
63 def get(self):
64 user = users.get_current_user()
65 if user:
66 self.response.headers['Content-Type'] = 'text/plain'
67 self.response.write('Hello, ' + user.nickname())
68 else:
69 self.redirect(users.create_login_url(self.request.uri))
70 71
72 def handle_404(request, response, exception):
73 logging.exception(exception)
74 response.write('ページが見つかりませんでした。')
75 response.set_status(404)
76 77
78 app = webapp2.WSGIApplication([
79 ('/', MainHandler),
80 ('/mypage', MyPageHandler)
81 ], debug=True)
82
83 app.error_handlers[404] = handle_404
14.3.2 確認
入力フォームからデータを追加し、次のことを確認します。
84 第14章 データストアを使う
• DatastoreAdminページを開きデータが追加されている
• Log Consoleに追加されたデータのkeyが出力されている
– 例)key=Key(‘Todo’, 5681726336532480)
14.3.3 解答
解答ドキュメントを参照してください。