Django中的TemplateView具有自定义状态代码

时间:2013-09-11 12:49:36

标签: django django-class-based-views

我的项目中有内部帐户隐私权限(例如,只有朋友可以看到用户的个人资料页面),我希望在这种情况下拥有自定义权限被拒绝页面。有没有办法从TemplateView返回状态代码等于403的响应?

这样的事情:

class PrivacyDeniedView(TempateView):
    template_name = '...'
    status_code = 403

我可以通过覆盖dispatch()来做到这一点,但也许Django已经开箱即用的解决方案

答:看起来没有通用解决方案。最好的方法是由@alecxe提出,但是作为@FoxMaSk建议将其封装在Mixin中

5 个答案:

答案 0 :(得分:7)

一种选择是覆盖TemplateView类的get()方法:

def get(self, request, *args, **kwargs):
    context = self.get_context_data(**kwargs)
    return self.render_to_response(context, status=403)

答案 1 :(得分:3)

虽然alecxe的回答有效,但我强烈建议您避免覆盖get;很容易忘记CBV可以有其他方法,如post,如果你压倒一个,你应该为其他方法做同样的事情。

实际上,不需要创建单独的视图来显示403错误; Django已经有django.http.HttpResponseForbidden。因此,不要重定向到您的视图,只需执行以下操作:

if not user.has_permission(): # or however you check the permission
    return HttpResponseForbidden()

或者,如果您想渲染特定模板:

if not user.has_permission(): # or however you check the permission
    return HttpResponseForbidden(loader.render_to_string("403.html"))

答案 2 :(得分:2)

您可以在视图中继承TemplateResponse并设置response_class。例如:

from django.template.response import TemplateResponse

class TemplateResponseForbidden(TemplateResponse):
    status_code = 403

class PrivacyDeniedView(TemplateView):
    response_class = TemplateResponseForbidden
    ...

此方法比其他建议更干,因为您无需复制和粘贴TemplateView中的任何代码(例如,对render_to_string()的调用)。

我在Django 1.6中测试了这个。

答案 3 :(得分:1)

我刚遇到这个问题。我的目标是能够在urls.py中指定状态代码,例如:

url(r'^login/error/?$', TemplateView.as_view(template_name='auth/login_error.html', status=503), name='login_error'),

因此,使用此主题中的先前答案作为创意启动者,我提出了以下解决方案:

class TemplateView(django.views.generic.TemplateView):

    status = 200

    def render_to_response(self, context, **response_kwargs):

        response_kwargs['status'] = self.status

        return super(TemplateView, self).render_to_response(context, **response_kwargs)

答案 4 :(得分:1)

这是一个老问题,但我在搜索时首先遇到过它。我正在使用不同的通用视图(ListView),其get的实现有点复杂,因此有点乱。我选择了这个解决方案:

def get(self, request, *args, **kwargs):
    response = super(ListView, self).get(request, *args, **kwargs)
    response.status_code = 403
    return response

这也允许我根据请求的某些参数来决定状态代码,在我的情况下,这对于旧式URL模式执行301重定向是必要的。

如果您不需要在方法中更改状态代码,那么cjerdonek's answer是理想的。