我的项目中有内部帐户隐私权限(例如,只有朋友可以看到用户的个人资料页面),我希望在这种情况下拥有自定义权限被拒绝页面。有没有办法从TemplateView返回状态代码等于403的响应?
这样的事情:
class PrivacyDeniedView(TempateView):
template_name = '...'
status_code = 403
我可以通过覆盖dispatch()来做到这一点,但也许Django已经开箱即用的解决方案
答:看起来没有通用解决方案。最好的方法是由@alecxe提出,但是作为@FoxMaSk建议将其封装在Mixin中
答案 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是理想的。