Google App Engineで「CRUD」Djangoフォーム編
2010/04/26 13:11:10
「Google App Engineで「CRUD」1ファイル+テンプレート版」の記事でベタにCRUDを作成したが、フォームやバリデーション部分をDjangoのフォームにやってもらったものを作ってみました。コード量は確かに減るし、バリデーションやエラー表示もやってくれるのでかなり便利。
確かに便利は便利なのだが…
app.yaml
main.py
template/list.html
template/view.html
template/add.html
template/edit.html
便利な反面、以下の問題が面倒。
・デザインをCSSで指定し、さらにクラスでそれを指定しなければならない。
・エラー表示はデフォルトで英語なので、新たに指定しなければならない。
う〜ん、バリデーション部分のみ利用するというのもありなのかな〜
application: jinling-ren version: 1 runtime: python api_version: 1 handlers: - url: .* script: main.py
main.py
#!/usr/bin/env python
#!-*- coding:utf-8 -*-
# Djangoフォームサンプル
# http://www.jinlingren.com/
from google.appengine.ext import webapp, db
from google.appengine.ext.webapp import util, template
from google.appengine.ext.db import djangoforms
import os
import cgi
import logging
class Book(db.Model):
title = db.StringProperty(required=True, verbose_name='タイトル')
author = db.StringProperty(required=True, verbose_name='著者')
modified = db.DateTimeProperty(auto_now=True)
created = db.DateTimeProperty(auto_now_add=True)
class AddForm(djangoforms.ModelForm):
class Meta:
model = Book
exclude = {}
class Root(webapp.RequestHandler):
def get(self):
self.redirect('/list')
class List(webapp.RequestHandler):
def get(self):
books = Book.all().order('-created')
html = template.render(
os.path.join(os.path.dirname(__file__), 'template', 'list.html'),
{
'books': books
}
)
self.response.out.write(html)
class View(webapp.RequestHandler):
def get(self, key):
book = db.get(db.Key(key))
html = template.render(
os.path.join(os.path.dirname(__file__), 'template', 'view.html'),
{
'book': book
}
)
self.response.out.write(html)
class Add(webapp.RequestHandler):
def get(self):
form = AddForm()
html = template.render(
os.path.join(os.path.dirname(__file__), 'template', 'add.html'),
{
'form': form
}
)
self.response.out.write(html)
def post(self):
try:
form = AddForm(data=self.request.POST)
if form.is_valid():
book = form.save()
self.redirect('/list')
else:
html = template.render(
os.path.join(os.path.dirname(__file__), 'template', 'add.html'),
{
'form': form
}
)
self.response.out.write(html)
except:
self.redirect('/add')
class Edit(webapp.RequestHandler):
def get(self, key):
book = db.get(db.Key(key))
form = AddForm(instance=book)
logging.info(type(form))
html = template.render(
os.path.join(os.path.dirname(__file__), 'template', 'edit.html'),
{
'key': key,
'form': form
}
)
self.response.out.write(html)
def post(self, key):
try:
book = db.get(db.Key(key))
form = AddForm(data=self.request.POST, instance=book)
if form.is_valid():
form.save()
self.redirect('/list')
else:
html = template.render(
os.path.join(os.path.dirname(__file__), 'template', 'edit.html'),
{
'key': key,
'form': form
}
)
self.response.out.write(html)
except:
self.redirect('/edit/'+key)
class Delete(webapp.RequestHandler):
def get(self, key):
try:
book = db.get(db.Key(key))
if book:
book.delete()
self.redirect('/list')
except:
self.redirect('/list')
def main():
application = webapp.WSGIApplication(
[
('/', Root),
('/list', List),
('/view/(\w+)', View),
('/add', Add),
('/edit/(\w+)', Edit),
('/delete/(\w+)', Delete)
],
debug=True)
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
template/list.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Djangoフォームサンプル</title>
</head>
<body>
<h1>List(一覧)</h1>
> <a href="/add">追加</a><br><br>
<table cellspacing="1" cellpadding="8" border="0" bgcolor="#999999">
<tr bgcolor="#EBEBEB">
<td> </td>
<td align="center">タイトル</td>
<td align="center">著者</td>
<td> </td>
<td> </td>
</tr>
{% for book in books %}
<tr bgcolor="#FFFFFF">
<td><a href="/view/{{ book.key }}">詳細</a></td>
<td>{{ book.title }}</td>
<td>{{ book.author }}</td>
<td><a href="/edit/{{ book.key }}">編集</a></td>
<td><a href="/delete/{{ book.key }}" onClick="if(confirm('本当に削除しますか?')){return true;}else{return false;}">削除</a></td>
</tr>
{% endfor %}
</table>
</body>
</html>template/view.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Djangoフォームサンプル</title>
</head>
<body>
<h1>View(参照)</h1>
> <a href="/list">一覧</a><br><br>
<table cellspacing="1" cellpadding="8" border="0" bgcolor="#999999">
<tr>
<td width="100" bgcolor="#EBEBEB">タイトル</td>
<td width="250" bgcolor="#FFFFFF">{{ book.title }}</td>
</tr>
<tr>
<td bgcolor="#EBEBEB">著者</td>
<td bgcolor="#FFFFFF">{{ book.author }}</td>
</tr>
</table>
</body>
</html>template/add.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Djangoフォームサンプル</title>
</head>
<body>
<h1>Add(追加)</h1>
> <a href="/list">一覧</a><br><br>
<form action="/add" method="post">
<table border="1" cellspacing="1" cellpadding="8" border="0">
{{ form }}
</table><br>
<input type="submit" value="追加する">
</form>
<br>
<font color="#FF0000">*</font>は必須項目
</body>
</html>template/edit.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Djangoフォームサンプル</title>
</head>
<body>
<h1>Edit(編集)</h1>
> <a href="/list">一覧</a><br><br>
<form action="/edit/{{ key }}" method="post">
<table border="1" cellspacing="1" cellpadding="8" border="0">
{{ form }}
</table><br>
<input type="submit" value="変更する">
</form>
<br>
<font color="#FF0000">*</font>は必須項目
</body>
</html>便利な反面、以下の問題が面倒。
・デザインをCSSで指定し、さらにクラスでそれを指定しなければならない。
・エラー表示はデフォルトで英語なので、新たに指定しなければならない。
う〜ん、バリデーション部分のみ利用するというのもありなのかな〜