仕様は、
・持ち金をチャージできる。
・チャージ時の総額と総利用額と残金を表示。
・使った時は、何に使ったかと金額を入力。
・過去20件の利用データを表示。
・過去100件の利用データ中の何に使ったかをドロップダウン表示して選択できる。
・エラーチェックはまだしていない。
・オモローと表示していた部分を「ご利用は計画的に。」に変更。
気づいたこと。知ったこと。
・djangoのテンプレートに渡す値にmodelを使えるのが管理が煩雑にならないので楽だと思った。
・GQLでSQLのTOP 20をやりたいときは、ORDER BY等の後にLIMIT 20とやる。
・ORDER BY等はおおむねSQLと同じ。
・時間制限のため、コードが汚い(エクスキューズです。)。
・datetime型を使う場合はdatetimeモジュールをインポートする。
・djangoのテンプレート側で四則演算が出来ない。
・スペルミスで結構エラーになった。
サンプルか修正したオブジェクトだけ表示。
・テンプレート
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="ja" xml:lang="ja" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{{ userName }}のお小遣い帳</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link href="./styles/styles.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="./scripts/util.js" ></script>
<script type="text/javascript" src="./scripts/index.js" ></script>
</head>
<body>
<div id="body">
<div id="header">
<div id="user">
お小遣い帳
</div>
<div id="navigationOperation" >■</div>
</div>
<div id="navigation" >
<div id="logonControl">
{{ userName }} <br />
<a href="{{ logoutUrl }}">ログオフ</a>
</div>
<div id="settings">
<form action="/" method="post">
<div>年間チャージ額:<br /><input type="text" name="chargedValue" value="{{ setting.chargedValue }}" tabindex="1" accesskey="1" /><br /></div>
<div>前回チャージ後総額:<br />{{ setting.properValue }}円<br /></div>
<div>総利用額:<br />{{ setting.totalPayment }}円<br /></div>
<div>残額:<br />{{ currentValue }}円<br /></div>
<div><input type="submit" value="設定" tabindex="2" accesskey="s" /></div>
{% if settingErrorMessage %}
<div class="errorMessage">{{ settingErrorMessage }} </div>
{% endif %}
</form>
</div>
</div>
<div id="contents">
<form action="/" method="post">
<div>使った内容:<select name="titles" tabindex="3">
<option value="" selected="selected"></option>
{% for value in titles %}
<option value="{{ value }}" >{{ value }}</option>
{% endfor %}
</select><input type="text" name="title" value="" tabindex="4" accesskey="c" /></div>
<div>使った金額:<input type="text" name="payment" value="" tabindex="5" accesskey="3" /><br /></div>
<div><input type="submit" value="設定" tabindex="6" accesskey="s" /></div>
{% if paymentErrorMessage %}
<div class="errorMessage">{{ paymentErrorMessage }} </div>
{% endif %}
</form>
<div id="list" >
過去20件の利用状況:
<table border="1" cellspacing="0" >
<tr>
<th>日付</th>
<th>使った内容</th>
<th>金額</th>
</tr>
{% for value in outputValues %}
<tr>
<td>{{ value.date }}</td>
<td>{{ value.title }}</td>
<td>{{ value.value }}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
<div id="footer">ご利用は計画的に。</div>
</div>
</body>
</html>
・データモデル
from google.appengine.ext import db
class UserMaster(db.Model):
author = db.UserProperty()
chargedValue = db.IntegerProperty()
totalPayment = db.IntegerProperty()
properValue = db.IntegerProperty()
class PaymentInfo(db.Model):
author = db.UserProperty()
title = db.StringProperty()
value = db.IntegerProperty()
date = db.DateTimeProperty(auto_now_add=True)
・index.py
import wsgiref.handlers
import cgi
import datetime
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.api import users
import models
import os
from google.appengine.ext.webapp import template
from google.appengine.ext.db import djangoforms
class MainPage(webapp.RequestHandler):
def view(self,user,settingErrorMessage = None,paymentErrorMessage = None):
settings = models.UserMaster.gql("where author = :author",author=user)
setting = None
if settings.count() > 0:
setting = settings[0]
else:
setting = models.UserMaster()
setting.author = user
setting.chargedValue = 600000
setting.properValue = setting.chargedValue
setting.totalPayment = 0
setting.put()
outputValues = models.PaymentInfo.gql("where author = :author order by date DESC LIMIT 20",author=user)
titles = self.titles(user)
template_values = {
'userName' : user.nickname(),
'logoutUrl': cgi.escape(users.create_logout_url("/")),
'setting' : setting,
'currentValue':setting.properValue - setting.totalPayment,
'outputValues': outputValues,
'titles': titles,
'settingErrorMessage': settingErrorMessage,
'paymentErrorMessage': paymentErrorMessage
}
path = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(path, template_values))
def titles(self,user):
selections = models.PaymentInfo.gql("where author = :author order by title",author=user)
values = []
prev = ''
for value in selections:
if prev != value.title:
values.append(value.title)
prev = value.title
return values
def get(self):
user = users.get_current_user()
if not user:
self.redirect(users.create_login_url(self.request.uri))
return
self.view(user)
def post(self):
user = users.get_current_user()
if not user:
self.redirect(users.create_login_url(self.request.uri))
return
if self.request.get('chargedValue'):
if self.request.get('chargedValue').isdigit():
settings = models.UserMaster.gql("where author = :author",author=user)
setting = settings[0]
setting.properValue = setting.properValue + int(self.request.get('chargedValue'))
setting.put()
else:
self.view(user,u'チャージ金額には数字を入力してください。')
return
else:
payment = models.PaymentInfo()
payment.author = user
if len(self.request.get('titles')) == 0:
payment.title = self.request.get('title')
else:
payment.title = self.request.get('titles')
payment.value = int(self.request.get('payment'))
payment.put()
settings = models.UserMaster.gql("where author = :author",author=user)
setting = settings[0]
setting.totalPayment = setting.totalPayment + payment.value
setting.put()
self.view(user)
def main():
application = webapp.WSGIApplication(
[('/', MainPage)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)
if __name__ == '__main__':
main()