Django 1.4 で Class-based views 使ってみた
Django は MTV フレームワークであって、 V の関数ベースのコーディングは知っていた。
けれど、最近 Class-based view があると聞いて、よく知らないので知るために使ってみた。
環境
ディレクトリ構成
- 適当な動作確認アプリなので、名前はごめんなさい。。。
- settings は分けている。
- staticfile で静的ファイルを修正して、collectstatic で static へ。 (ここら辺割と適当ですみません。)
$ tree diary diary ├── conf │   ├── diary.db │   ├── __init__.py │   ├── settings │   │   ├── base.py │   │   ├── conn.py │   │   ├── dev.py │   │   ├── __init__.py │   │   └── prod.py │   ├── urls.py │   └── wsgi.py ├── diary │   ├── forms.py │   ├── __init__.py │   ├── models.py │   ├── tests.py │   └── views.py ├── manage.py ├── static │   └── js │   └── main.js ├── staticfiles │   └── js │   └── main.js └── templates └── layout.html
views.py
- エラー時の処理は未実装。。。
- csrf トークンは csrf_protect decorator なくても標準で入るみたい。
- どこかで、Django に Class-based Views が入った経緯を押さえたいと書いていたのがあった。自分も知りたいけど、公式の 『Writing Web applications 〜』 からの 2段落がそれかな。
# coding: utf-8 from django.views.generic import ( ListView, CreateView, UpdateView, DeleteView, ) import diary.forms import diary.models class HomeView(ListView): """ 一覧を表示する """ template_name = 'layout.html' context_object_name = 'comments' queryset = diary.models.Comment.objects.all()[:100] def get_context_data(self, **kwargs): context = super(self.__class__, self).get_context_data(**kwargs) # コメント用フォームを生成する context['comment_form'] = diary.forms.CommentForm() return context class CreateCommentView(CreateView): """ コメントを追加する """ model = diary.models.Comment form_class = diary.forms.CommentForm success_url = '/' class UpdateCommentView(UpdateView): """ コメントを更新する """ template_name = 'layout.html' model = diary.models.Comment success_url = '/' class DeleteCommentView(DeleteView): """ コメントを削除する """ model = diary.models.Comment success_url = '/'
その他もろもろ
urls.py
update, delete は pk を入れないと対象のデータが取得できないエラーで動作せず。update、delete の各Class に get_object を実装するも、url に pk がないと動かない。
from django.conf.urls import patterns, include, url import diary.views # Uncomment the next two lines to enable the admin: # from django.contrib import admin # admin.autodiscover() urlpatterns = patterns('', # Examples: # url(r'^$', 'conf.views.home', name='home'), # url(r'^diary/', include('diary.foo.urls')), #url(r'^$', 'diary.views.home', name='home'), url(r'^$', diary.views.HomeView.as_view(), name='home'), url(r'^diary/create$', diary.views.CreateCommentView.as_view(), name='create_comment'), url(r'^diary/(?P<pk>\d+)/update$', diary.views.UpdateCommentView.as_view(), name='update_comment'), url(r'^diary/(?P<pk>\d+)/delete$', diary.views.DeleteCommentView.as_view(), name='delete_comment'), # Uncomment the admin/doc line below to enable admin documentation: # url(r'^admin/doc/', include('django.contrib.admindocs.urls')), # Uncomment the next line to enable the admin: # url(r'^admin/', include(admin.site.urls)), )
models.py
# coding: utf-8 from datetime import datetime from django.db import models class CommentManager(models.Manager): pass class Comment(models.Model): objects = CommentManager() name = models.CharField( 'name', max_length=256) content = models.CharField( 'content', max_length=256) ctime = models.DateTimeField( 'date created', auto_now_add=True, blank=True) utime = models.DateTimeField( 'date updated', auto_now=True, blank=True) class Meta: db_table = 'comment' # 単数形 verbose_name = 'comment' # 複数形 verbose_name_plural = 'comments'
forms.py
# coding: utf-8 from django.forms import ModelForm import diary.models class CommentForm(ModelForm): class Meta: model = diary.models.Comment fields = ('name', 'content')
参考
- Class-based generic views Django 公式、1.4向け
- 偏った言語信者の垂れ流し - Django1.3のClass-based generic viewsを使う tokibito さん、1.3向け。実装例も書かれていて大変わかり易い。