Generic Viewでちょっと複雑なことをする

Generic viewをうまく使うとコードの量も減るし、いいよ、と書いている人を発見。
Django tips: get the most out of generic views

加えてちょうど良いタイミングでGeneric viewsでちょっと複雑なことすると使えないと困っている方が。

ちょっとした検索結果を表示したい時にジェネリックビューが使えない。
(もしかしたらあるのかもしれないけど、見つけられなかった。)

Djangoのジェネリックビューで検索結果を表示してみる - 記憶は削除の方向で

ちょうど良い機会なので、上で紹介されているTipsのとおりにGeneric viewを使って
検索結果を出す練習をしてみた。

モデルは全く同じもの。

# -*- encoding: utf-8 -*-
from django.db import models

class Author(models.Model):
    name = models.CharField(maxlength=200)
    
class Book(models.Model):
    name = models.CharField(maxlength=200)
    authors = models.ManyToManyField(Author)

urls.pyは次のとおり。
(正規表現Unicodeフラグを渡す方法はなさそうだったので強引に)

# -*- encoding: utf-8 -*-
from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^(?P<author>[^/]+?)/$', 'myproj.book.views.author_list'),
)

ここはほぼTipsにあるまま

# -*- encoding: utf-8 -*-
from django.views.generic.list_detail import object_list
from myproj.book.models import Book
# Create your views here.

def author_list(request, author):
    book_list = Book.objects.filter(authors__name__exact=author)
    return object_list(request, queryset=book_list, extra_context={'author_name': author})

テンプレート(base.htmlはhttp://www.djangoproject.com/documentation/templates/#template-inheritanceのやつ)

{% extends "base.html" %}

{% block title %}{{ author_name }}の書籍{% endblock %}

{% block content %}
    <h1>{{ author_name }}の書籍</h1>
    {% if object_list %}
        <table>
          <tr>
	    <th>書名</th>
	    <th>著者</th>
	  </tr>
        {% for book in object_list %}
          <tr>
	    <td>{{ book.name }}</td>
	    <td>{{ book.authors.all|join:", "}}</td>
          </tr>
        {% endfor %}
	</table>
    {% else %}
        一冊も登録されていません。
    {% endif %}
{% endblock %}

本当にほとんどコード書かなくていいなぁ。すごい。