Djangoでジェネリックビューの続き
via http://d.hatena.ne.jp/Voluntas/20070325/1174799784
via http://d.hatena.ne.jp/akkt/20070325/1174809264
いきなり2人からトラックバック頂いて少々焦り気味ですが。
コメントだと長くなりそうなので、こちらに書いてみます。
def search_auther(request, author_id): books = Book.objects.filter(authors__id=author_id) return list_detail.object_list(request, queryset=books)汎用ビュー - Twisted Mind
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})Generic Viewでちょっと複雑なことをする - rants
どちらも同じような感じだと思います。
- ビューを書いて、urls.pyでそれを指すようにする。
- ビューでクエリセットを取得する。
- 結果をジェネリックビューに渡す。
自分も最初はそう書いてました。
だんだんモデルが複雑になってきたとき、同じようなビューがたくさんあることに気付いたんですね。
同じようなコードだからまとめられるんじゃ?と思って、突き詰めていったら前回のコードができたと。
最終的には、同じようにジェネリックビューにお任せしてます。
例えば、前回のモデルを拡張してみます。
# -*- encoding: utf-8 -*- from django.db import models class Author(models.Model): name = models.CharField(maxlength=200) class Publisher(models.Model): name = models.CharField(maxlength=200) class Genre(models.Model): name = models.CharField(maxlength=200) class Book(models.Model): name = models.CharField(maxlength=200) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) genres = models.ManyToManyField(Genre)
で、urls.pyはこう書けます。
urlpatterns = patterns('', (r'^$', 'django.views.generic.list_detail.object_list', {'queryset':Book.objects.all()}), (r'^(author/(?P<author_id>\d+)/)?(publisher/(?P<publisher_id>\d+)/)?(genre/(?P<genre_id>\d+)/)?$', 'djangotest.book.urls.lookup', { 'allow_empty' : True, 'paginate_by' : 10, 'filters' : { 'author_id' : 'authors__id' , 'publisher_id' : 'publisher__id', 'genre_id' : 'genres__id'}, 'query' : lambda x: Book.objects.filter(x) }) )
http://localhost:8000/book/
これだったら書籍一覧が表示されて、
http://localhost:8000/book/author/1/publisher/1/
これは著者IDが1で出版社IDが1の書籍一覧、
http://localhost:8000/book/publisher/1/genre/1/
これは出版社IDが1でジャンルIDが1の書籍一覧が表示されます。
と、これくらいの簡単な検索なら、追加のビューを書かずにカバーできます。
ジェネリックビューが使えないと言ってるわけではないですよー。
(URLが変態的なのは否定できませんが・・・)