3

学校の記録 Web アプリを作成しています。スタッフ ユーザーが正しい URL にアクセスすることで、任意の生徒のユーザー データ ページを表示できるようにしたいのですが、生徒が互いのページにアクセスできるようにする必要はありません。ただし、両方の URL に同じビュー関数を使用しています。

@user_is_staffオブジェクトの存在に基づいて動作するデコレータがありuser.staffます。代わりに、生徒ユーザーにはuser.pupilオブジェクトがあります。ユーザーは と の両方の.staffエントリ.pupilを持つことはできないため、これらは当然離散的です。

urls.py

(r'^home/(?P<subject>[^/]+)/$', 'myproject.myapp.views.display_pupil')
(r'^admin/user/(?P<user>\d+)/(+P<subject>[^/]+)/$', 'myproject.myapp.views.display_pupil')

ビュー.py

@login_required
def display_pupil(request, subject, pupil=None):
    if pupil:
        try:
            thepupil = get_object_or_404(Pupil, id = pupil, cohort__school = request.user.staff.school)
        except Staff.DoesNotExist:
            return HttpResponseForbidden()
    else:
        thepupil = request.user.pupil
    thesubject = get_object_or_404(Subject, shortname = subject)
    # do lots more stuff here
    return render_to_response('pupilpage.html', locals(), context_instance=RequestContext(request))

このようにするとうまくいきますが、特に私の '@user_is_staff' デコレータには、ここでの 403 エラーよりもエレガントなログイン ページへのリダイレクトがあるため、非常にハッキリしています。

私が知らないのは、関数がkwarg@user_is_staffでアクセスされた場合にのみデコレータを関数に適用する方法です。pupil実際のビュー関数にはさらに多くのコードがあるため、2 つ目のコードは非常に非 DRY になるため、書きたくありません。

4

1 に答える 1

2

特定の生徒用と現在のユーザー用の 2 つの個別のビューと、共有ロジックを含むユーティリティ関数が必要なようです。

@login_required:
def display_current_pupil(request, subject):
    thepupil = request.user.pupil
    return display_pupil_info(request, subject, thepupil)

@user_is_staff
def display_pupil(request, subject, pupil):
    thepupil = get_object_or_404(Pupil, id=pupil, cohort__school=request.user.staff.school)
    return display_pupil_info(request, subject, thepupil)

def display_pupil_info(request, subject, thepupil):
    thesubject = get_object_or_404(Subject, shortname=subject)
    # do lots more stuff here
    return render_to_response('pupilpage.html', locals(), context_instance=RequestContext(request))
于 2012-07-24T18:23:05.193 に答える