8

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

像这样的东西:

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

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

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

4

5 回答 5

11

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

def get(self, request, *args, **kwargs):
    context = self.get_context_data(**kwargs)
    return self.render_to_response(context, status=403)
于 2013-09-11T12:56:40.220 回答
4

您可以在视图中进行子类化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 中对此进行了测试。

于 2014-01-24T03:04:12.570 回答
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"))
于 2013-09-11T22:52:36.590 回答
2

我也刚遇到这个问题。我的目标是能够在 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)
于 2014-02-24T13:20:15.453 回答
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 的答案是理想的。

于 2016-12-02T00:48:39.327 回答