Djangoの汎用ビューを使ってみた

Djangoの汎用ビューをはじめて使ってみたのですが、なかなか面白いです。
今のところ表示を任せてみていますが、データベースの内容表示に関してはあれで十分任せれます。
大まかに理解をしていたつもりでしたが、実装するのにずいぶん苦労しましたが、
使えるようになると今まで自分で作っていたビューを何も書かずに乗せれる(テンプレートも頭のクエリセットを適切に変えればすぐに適応できる。
わかってしまえばこんなに楽なのかと驚いてしまうのですが。


ちなみに、当たり前といえば当たり前の話ですが
ドキュメントや取り扱ったブログでは、querysetの定義にinfo_dictの辞書オブジェクトを使うことが多いです。これはもちろん別に定義した辞書オブジェクトも使えます。
注意点として中身のquerysetなどの定義がDjangoの要求にこたえれればなんでもよいようですね。

汎用ビュー — Django v1.0 documentation

info_dict = {
    'queryset':Res.objects.all(),
    }

tag_dict = {
    'queryset':Tags.objects.all(),
    'slug_field':'onetag',
    }
    
urlpatterns = patterns('',
    (r'^$', 'django.views.generic.list_detail.object_list', info_dict),
    (r'^res/(?P<object_id>\d+)/$', 'django.views.generic.list_detail.object_detail', info_dict),
    (r'^tag/(?P<slug>\w+)/$', 'django.views.generic.list_detail.object_detail', dict(tag_dict, template_name='myapp/tags_reslist.html')),
    (r'^post/$', 'mysite.myapp.views.post'),
)

こんな感じで、tag_dictのように作ることもできます。
簡単に解説すると、'django.views.generic.list_detail.object_detail'の必須引数は、辞書オブジェクトと、モデルオブジェクトのID or 適当な文字列の定義 です。

django.views.generic.list_detail.object_detail¶

個々のオブジェクトを表現するページです。

解説:

個々のオブジェクトを表現するページです。

必須の引数:

*

queryset: オブジェクトの入っている QuerySet です。
*

object_id または (slug と slug_field) が必要です。

object_id を使う場合、ページに表示するオブジェクトの主キーとなる フィールドの値を指定せねばなりません。

そうでない場合には、 slug にオブジェクトの slug を、 slug_field に QuerySet に指定したモデルの slug フィールド名を 指定せねばなりません。 slug_field のデフォルト値は 'slug' で す。

~/tag/の部分はタグの単語の指定を行うので、この部分は文字列の定義をおこうなう必要があります。
辞書オブジェクトのtag_dictにquerysetと'slug_field'を指定します。今回の場合は、タグの単語を格納している'onetag'がおいてあります。
そして、URLディスパッチャには(?P\w+)と指定するわけです。slug_fieldがslugに対応しているようです。
これで、 ~/tag/tag1/ とURLに書いて要求すると、「tag1」というタグと絡む内容を引っ張ってこれるようになります。


次はユーザー認証に取り組みたいところです。
いろいろと悩むものですが、処理の比率をどこに持たせればよいのか悩むものです。
Viewsに任せるか、テンプレートにさせるのかとかですか。

追記

忘れていました。汎用ビューには名前をつけれます。

    (r'^$', 'django.views.generic.list_detail.object_list', info_dict , 'reslist'),

'reslist'が、~/の名前です。関連付けています。
すると、Views.pyで

    return HttpResponseRedirect(reverse('reslist'))

こんな使い方ができます。reverse()関数で簡単に拾うことが可能です。