HOME > ブログ > Google App Engineで「CRUD」Djangoフォーム編

Google App Engineで「CRUD」Djangoフォーム編

Google App Engineで「CRUD」1ファイル+テンプレート版」の記事でベタにCRUDを作成したが、フォームやバリデーション部分をDjangoのフォームにやってもらったものを作ってみました。
コード量は確かに減るし、バリデーションやエラー表示もやってくれるのでかなり便利。

確かに便利は便利なのだが…



app.yaml
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>&nbsp;</td>
    <td align="center">タイトル</td>
    <td align="center">著者</td>
    <td>&nbsp;</td>
    <td>&nbsp;</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で指定し、さらにクラスでそれを指定しなければならない。
・エラー表示はデフォルトで英語なので、新たに指定しなければならない。

う〜ん、バリデーション部分のみ利用するというのもありなのかな〜
| Google App Engine | Comment:2 |
コメント
Jacoby
Supeoirr thinking demonstrated above. Thanks!
Supeoirr thinking demonstrated above. Thanks!
| | 2012/02/01 13:56:02
mhfbseuqkyq
Slw9rw <a href="http://igjcqugdvuwg.com/">igjcqugdvuwg</a>
Slw9rw <a href="http://igjcqugdvuwg.com/">igjcqugdvuwg</a>;
| | 2012/02/02 00:52:00
コメント投稿












画像リロード
*半角の小英字、数字で構成されています