3

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

我有一个@user_is_staff基于user.staff对象存在的工作装饰器。学生用户有一个user.pupil对象。这些自然是离散的,因为没有用户可以同时拥有 a.staff.pupil条目。

网址.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真实视图函数中有更多代码,所以我不想写第二个,因为那将是严重的非 DRY。

4

1 回答 1

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 回答