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

Django中带有自定义状态代码的TemplateView,django,django-class-based-views,Django,Django Class Based Views,我在我的项目中拥有内部帐户隐私权限(例如,只有朋友才能查看用户的个人资料页面),我希望在这种情况下拥有自定义权限被拒绝页面。有没有办法从TemplateView返回状态代码为403的响应 大概是这样的: class PrivacyDeniedView(TempateView): template_name = '...' status_code = 403 我可以通过重写dispatch()来实现这一点,但Django可能有现成的解决方案 答:看起来没有通用的解决方案。最好的方

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

大概是这样的:

class PrivacyDeniedView(TempateView):
    template_name = '...'
    status_code = 403
我可以通过重写dispatch()来实现这一点,但Django可能有现成的解决方案

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

一个选项是覆盖
TemplateView
类的方法:

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

虽然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"))

您可以在视图中对
templaterresponse
进行子类化,并设置
response\u 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中对此进行了测试。

我也遇到了这个问题。我的目标是能够在URL.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)

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

def get(self, request, *args, **kwargs):
    response = super(ListView, self).get(request, *args, **kwargs)
    response.status_code = 403
    return response
这还允许我根据请求的一些参数来决定状态代码,这在我的案例中是对旧式URL模式执行301重定向所必需的


如果您不需要在方法中更改状态代码,那么这是理想的选择。

谢谢。我知道这个解决方案,但对我来说,它看起来有点难看(如果我不是worng@MaxKharandziuk,事实上不是这样的,
TemplateView
继承了提供它的
BaseView
。我的意思是,我更愿意更改状态代码,正如我在问题中提到的:)可能是,然后你可以做一个混音,并在你的
类foobar中使用它(TemplateView,FoobarMixin)
?查看我刚刚发布的答案,它与上面包含的假设代码片段非常相似。好主意。将其放入其中的最佳方法是什么?如果我想使其具有条件,而不是始终呈现403。