Django:根据引用URL限制对视图的访问

时间:2012-07-24 16:54:32

标签: django decorator user-accounts

我正在创建一个学校记录webapp。我希望员工用户能够通过访问正确的URL来查看任何学生的用户数据页面,但不允许学生访问彼此的页面。但是我对两个网址都使用相同的视图功能。

我有一个基于@user_is_staff对象存在的工作user.staff装饰器。 Pupil用户改为使用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')

views.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))

这样做可行,但感觉非常hacky,特别是因为我的'@user_is_staff'装饰器有更优雅的重定向到登录页面而不是403错误。

我不知道的是,只有在使用@user_is_staff kwarg访问函数时,如何将pupil装饰器应用于该函数。在真实视图函数中有更多的代码,所以我不想写第二个,因为那将是严重的非DRY。

1 个答案:

答案 0 :(得分: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))