[Django] 日本ひげ男協会のサイトを作成する。その6

注意

この記事は、id:SumiTomohiko:20070126:1169824898の続きです。

環境

この記事の内容は、Ubuntu 6.10, Python 2.4, Django 0.95で確認しました。

メニュー

これまで会員登録や一覧画面などを実装してきましたが、それらはどれもURLを直に指定して動作させてきました。いい加減、メニューが欲しいところです。というわけで、今回はメニューを実装します。

メニューを実装するに辺り、問題となるのは、テンプレート内でユーザがログインしているのか、それとも匿名ユーザであるのかを見分けることです。なぜならば、ユーザの種類によって、表示するメニューが以下のように異なるからです。

ユーザの種類 メニュー
匿名ユーザ 会員登録
匿名ユーザ ログイン
ログインユーザ 編集・退会
ログインユーザ ログアウト

こういった要望に応えるため、Djangoでは、コンテキストプロセッサという仕組みを設けています。コンテキストプロセッサとは、要するに辞書を返す関数(または呼び出し可能なオブジェクト)です。返された辞書が、テンプレートに渡る変数に追加されます。

テンプレートに渡す変数の名前は、"user_id"とします。ログインユーザならば、この値はUserオブジェクトのIDとなり、匿名ユーザならばNoneであるようにします。このようなコンテキストプロセッサは、次のように記述できます。記述するファイルは、user/context_processors.pyです。

def user_id(request):
    try:
        user_id = request.session[USER_ID_KEY]
    except KeyError:
        user_id = None

    return { "user_id": user_id }

次に、このコンテキストプロセッサを使うように、汎用ビューを設定します。修正するのはuser/urls.pyです(context_processor.locationというコンテキストプロセッサも追加していますが、これについてはまたの機会に触れたいと思います)。

    (r'^list/$', 'django.views.generic.list_detail.object_list', 
        { 'queryset': User.objects.all(), 
          'allow_empty': True, 
          'paginate_by': 20, 
          'context_processors': 
            [context_processors.user_id, context_processors.location] }), 

これで、テンプレート内でuser_idという変数が使えるようになりました。テンプレートでは、以下のようにメニューを記述します。

<div class="menu">
    <p>
        {% if user_id %}
        <a href="{{ location }}/user/edit/{{ user_id }}">編集・退会</a>
        &nbsp;
        <a href="{{ location }}/user/logout/">ログアウト</a>
        {% else %}
        <a href="{{ location }}/user/add/">会員登録</a>
        &nbsp;
        <a href="{{ location }}/user/login/">ログイン</a>
        {% endif %}
    </p>
</div>

メニューの実装は、以上で終了です。匿名ユーザの場合は、

となり、ログインすると、

となります。