Django Applicationを作る
ちょっと意味のあるアプリケーションとして、TODO管理機能を作っていくことにします。
Djangoと同じく、以下のコマンドでアプリケーションが生成されます。
manage.py startapp todo
これによりtodoフォルダができますので、中身を確認すると、以下のファイル・フォルダ群ができています。
media/ models.py templates/ views.py __init__.py
まず、Todo情報を表すモデルクラスを作成します。先ほど生成されたmodels.pyファイルに、以下のコードを加えました。
/todo/models.py
from google.appengine.ext import db from django.contrib.auth.models import User class Task(db.Model): user = db.ReferenceProperty(User) title = db.StringProperty() create_time = db.DateTimeProperty(auto_now_add=True) limit_time = db.DateTimeProperty()
次に、このTodo情報を閲覧するメソッドを用意します。先ほど生成されたviews.pyファイルに、以下のコードを加えました。
/todo/views.py
from django.views.generic.list_detail import object_list from ragendja.template import render_to_response from todo.models import Task def list_tasks(request): if not request.user.is_authenticated(): return render_to_response(request, "login.html") queryset = Task.all().filter("user", request.user) return object_list(request, queryset, paginate_by=20)
ここでは、DjangoのGeneric View(汎用ビュー)を利用することにしました。これに対応する一覧表示画面のテンプレートを用意します。汎用ビューの命名規則に沿った名前(この場合はtask_list.html)にしておけば、views.pyでテンプレート名を指定する必要はありません。
/todo/templates/task_list.html
{% extends "base.html" %} {% block head_title %}TODOリスト{% endblock %} {% block body_main %} <table> <tr><th>タイトル</th><th>締切</th></tr> {% for task in object_list %} <tr><td>{{ task.title }}</td><td>{{ task.limit_time|date:"Y-m-d" }}</td></tr> {% endfor %} </table> <div> {% if has_previous %} <a href="{% url todo.views.list_tasks %}?page={{ previous }}">前へ</a> {% endif %} {% if has_next %} <a href="{% url todo.views.list_tasks %}?page={{ next }}">次へ</a> {% endif %} </div> {% endblock %}
ページ下部の{% if has_previous %}...で始まる個所は、ページング処理を記述しています。
最後に、todoフォルダ内にurls.pyを用意し、トップのurls.pyから呼び出されるようにします。また、setting.pyでtodoアプリケーションに関して追記します。
/todo/urls.py
# -*- coding: utf-8 -*- from django.conf.urls.defaults import * from ragendja.urlsauto import urlpatterns urlpatterns = patterns('todo.views', (r'^$', 'list_tasks'), )
/urls.py
urlpatterns = patterns('', (r'^$', 'topapp.views.welcome'), (r'^todo/', include('todo.urls')),
/settings.py
INSTALLED_APPS = (
...中略...
'todo',
)
これで、Todo一覧のページができました。
同じ要領で、Todoタスクの追加ページを作ることにします。まず、Todoタスク追加フォームを表すModelFormクラスを作成します。todoフォルダ内に、新たにforms.pyファイルを作って、以下の内容を記述しました。
/todo/forms.py
from django import forms from todo.models import Task class TaskForm(forms.ModelForm): user = forms.CharField(widget=forms.HiddenInput, required=False) title = forms.CharField(max_length=100, required=True, label=u"タイトル", help_text=u"(必須)") limit_time = forms.DateTimeField(required=False, label=u"締切", help_text=u"(任意)yyyy-mm-ddの形式で入力してください") class Meta: model = Task exclude = ('create_time')
create_timeは自動生成されるものを利用するので、excludeに指定してユーザからの入力対象外としました。また、userにはログインユーザを登録する予定なので非表示(hidden)の入力フォームとしました。
次に、Todoタスク追加フォームを処理するメソッドをviews.pyに記述します。
/todo/views.py
from django.core.urlresolvers import reverse from django.views.generic.create_update import create_object def add_task(request): if not request.user.is_authenticated(): return render_to_response(request, "login.html") request.POST = request.POST.copy() request.POST["user"] = str(request.user.key()) return create_object(request, form_class=TaskForm, post_save_redirect=reverse('todo.views.list_tasks'))
ここでも、汎用ビューを利用しています。続いて、汎用ビューの命名規則に沿った追加フォームを作ります。
/todo/templates/task_form.html
{% extends "base.html" %} {% block head_title %}TODO追加{% endblock %} {% block body_main %} <form action="" method="post"> <table> {{ form.as_table }} <tr><td colspan="2"> <input type="submit" value="{% if object %}編集{% else %}追加{% endif %}" /> </td></tr> </table> </form> <a href="{% url todo.views.list_tasks %}">一覧へ戻る</a> {% endblock %}
最後に、urls.pyに以下の記述を追加して完了です。
/todo/urls.py
urlpatterns = patterns('todo.views', (r'^$', 'list_tasks'), (r'^create$', 'add_task'),
manage.py runserverコマンドで開発サーバを立ち上げて確認し、manage.py updateでアップロードしました。
このままだとTODOタスクは増えていく一方なので、次から、TODOタスクの編集と削除処理を作っていこうと思います。