7: 2015-07-20 (月) 17:01:01 njf[6] [7] [8] | 8: 2015-07-31 (金) 17:50:04 njf[6] [9] [10] | ||
---|---|---|---|
Line 213: | Line 213: | ||
データモデルは初期化の時にidというパラメータを指定することで、次からget_by_idというメソッドでデータを取得することが可能になり、一意のidがある場合はこれでデータの取り出しを行うと便利です。今回はデータは1つしか無いので固定でidを与えています。 | データモデルは初期化の時にidというパラメータを指定することで、次からget_by_idというメソッドでデータを取得することが可能になり、一意のidがある場合はこれでデータの取り出しを行うと便利です。今回はデータは1つしか無いので固定でidを与えています。 | ||
+ | *ユーザ-登録処理 [#a1528de1] | ||
+ | 上記ユーザーIDの生成処理を使うと、ユーザー登録処理は以下のようになります。 | ||
+ | class NjfEntry(webapp2.RequestHandler): | ||
+ | def post(self): | ||
+ | self.response.headers['Content-Type'] = "text/plain; charset=utf-8" | ||
+ | userId = getUserId() | ||
+ | password = random.randint(1000,1000000) | ||
+ | userData = UserData(id = str(userId) + "_" + str(password)) | ||
+ | userData.userId = userId | ||
+ | userData.password = password | ||
+ | userData.data = {} | ||
+ | userData.put() | ||
+ | returnData = {} | ||
+ | returnData["userId"] = userId | ||
+ | returnData["password"] = password | ||
+ | self.response.write(json.dumps(returnData)) | ||
+ | パスワードは乱数にしています。桁数があまり小さいと偶然正解する確率が高くなるので1000以上1000000未満としています。 | ||
+ | ここでuserDataにユーザーIDとパスワードを連結した物をIDとして与えています。これはユーザーIDとパスワードが変更されない事を前提としています。パスワード変更をユーザーに許すならこの方法はあまり良くないでしょう。その場合はidは使わずにデータを検索する必要があります。今回は変更はしないのでこれで問題ありません。 | ||
+ | 戻り値はユーザーIDとパスワードをjsonで送っています。 | ||
+ | |||
+ | *ログイン処理 [#q19f2920] | ||
+ | |||
+ | ログイン処理ではユーザーIDとパスワードをチェックして正しければデータを返し、そうでなければ-1を返します。 | ||
+ | |||
+ | class NjfLogin(webapp2.RequestHandler): | ||
+ | def post(self): | ||
+ | self.response.headers['Content-Type'] = "text/plain; charset=utf-8" | ||
+ | userId = self.request.get('userId') | ||
+ | password = self.request.get('password') | ||
+ | |||
+ | userData = getUserData(userId, password) | ||
+ | if userData: | ||
+ | self.response.write(json.dumps(userData.data)) | ||
+ | else: | ||
+ | self.response.write("-1") | ||
+ | |||
+ | ここでgetUserDataは以下のような、ユーザーIDとパスワードからユーザーデータを返す関数です。idにユーザーIDとパスワードを連結した物を使っているのでこのようにシンプルになります。 | ||
+ | |||
+ | def getUserData(userId,password): | ||
+ | ud = UserData.get_by_id(id=userId+"_"+password) | ||
+ | return ud | ||
+ | |||
+ | *セーブ処理 [#j2390dc0] | ||
+ | 最後に保存処理です。ユーザーIDとパスワードをチェックしてデータを保存します。成功した場合は空のjsonデータを返しています。失敗した場合は-1を返しています。 | ||
+ | |||
+ | class NjfSave(webapp2.RequestHandler): | ||
+ | |||
+ | def post(self): | ||
+ | self.response.headers['Content-Type'] = "text/plain; charset=utf-8" | ||
+ | userId = self.request.get('userId') | ||
+ | password = self.request.get('password') | ||
+ | data = self.request.get('data') | ||
+ | userData = getUserData(userId, password) | ||
+ | if userData: | ||
+ | jsonData = json.loads(data) | ||
+ | deepJsonCopy(jsonData, userData.data) | ||
+ | userData.put() | ||
+ | self.response.write("{}") | ||
+ | else: | ||
+ | self.response.write("-1") | ||
+ | |||
+ | ここでdeepJsonCopy関数は以下のようにjsonデータを再帰的にコピーする関数です。 | ||
+ | |||
+ | def deepJsonCopy(fromData,toData): | ||
+ | for key, value in fromData.iteritems(): | ||
+ | if isinstance(value,dict): | ||
+ | if not toData.has_key(key): | ||
+ | toData[key] = {} | ||
+ | deepJsonCopy(fromData[key],toData[key]) | ||
+ | else: | ||
+ | toData[key] = fromData[key] | ||
+ | |||
+ | pythonのjsonライブラリにはディープコピー関数があるのですが、入れ子になったオブジェクトには対応していないようなので自作しています。 | ||
+ | この関数を使うことによって、必要なデータだけをサーバーに送って保存することが可能になります。 | ||
+ | |||
+ | GAEでは転送量も課金対象になります。また、そうで無くてもやはり転送量は少なければ少ないほどユーザーの待ち時間は少なくなります。保存データが多い場合にはなるべく差分だけを送信した方が良いでしょう。 | ||
+ | しかし、差分だけを送信するとクライアント側とサーバー側で同期が狂いやすくなります。たとえば2つ同時にブラウザを立ち上げてそれぞれで矛盾するようなデータを送信すると、両方サーバーで保存されてしまいます。このような場合にどうするかを考慮する必要が出てきます。 | ||
+ | |||
+ | 毎回全てのデータを上書きするのならその心配はありません。もしデーター量が少ないならつねに全データを送るのをお勧めします。 | ||
+ | |||
+ | 以上でサーバーサイドは終わりです。次にクライアントサイドを解説します。 | ||
準備中 | 準備中 |
(This host) = https://njf.jp