学校の記録 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 になるため、書きたくありません。