Class Based Viewのシンプルな実装「Django Vanilla Views」
Django Vanilla Views - Beautifully simple class based views
DjangoのClass-Based-Viewは継承関係が複雑で、ちょっとソースを見てフックポイントを確認したいっていうときに結構めんどくさい。
Django Vanilla Viewsは機能はそのままで実装をシンプルにして使いやすくしたもの。
図を見ると、○○Mixinがなくなり、継承関係が浅くなっているのがわかる。
適当なサンプルを作って動きを比べてみた。
以下のコードでClassBasedViewを使った一覧表示、新規登録、更新、削除ができる。
models.py
from django.db import models class Person(models.Model): name = models.CharField(max_length=100) def __unicode__(self): return self.name
views.py
from django.http import HttpResponse from django.core.urlresolvers import reverse_lazy #from django.views.generic import CreateView, ListView, UpdateView, DeleteView from vanilla import CreateView, ListView, UpdateView, DeleteView from apps.models import Person class PersonListView(ListView): model = Person class PersonCreateView(CreateView): model = Person success_url = reverse_lazy('person:list') class PersonUpdateView(UpdateView): model = Person success_url = reverse_lazy('person:list') class PersonDeleteView(DeleteView): model = Person success_url = reverse_lazy('person:list')
urls.py
from django.conf.urls import patterns, include, url urlpatterns = patterns('', url('^person/', include('apps.urls', namespace='person')))
apps/urls.py
# coding=utf-8 from django.conf.urls import patterns, url from .views import PersonDetailView, PersonListView, PersonCreateView, PersonUpdateView, PersonDeleteView urlpatterns = patterns('', url(r'^$', PersonListView.as_view(), name='list'), url(r'^new$', PersonCreateView.as_view(), name='new'), url(r'^edit/(?P<pk>\d+)$', PersonUpdateView.as_view(), name='edit'), url(r'^delete/(?P<pk>\d+)$', PersonDeleteView.as_view(), name='delete'))
person_list.html
<h1>persons</h1> <ul> {% for person in object_list %} <li>{{ person }} : <a href="{% url "person:edit" person.id %}">edit</a> <a href="{% url "person:delete" person.id %}">delete</a> </li> {% endfor %} </ul> <a href="{% url 'person:new' %}">New</a>
person_form.html
<form method="post">{% csrf_token %} {{ form.as_p }} <input type="submit" value="Submit"/> </form>
person_confirm_delete.html
<form method="post">{% csrf_token %} Are you sure you want to delete "{{ object }}" ? <input type="submit" value="Submit"/> </form>
ClassBasedViewをvanillaモジュール、django.views.genericモジュールで入れ替えても挙動は全く同じになる