【问题标题】:TemplateView in Django with custom status code带有自定义状态码的 Django 中的 TemplateView
【发布时间】:2013-09-11 12:49:35
【问题描述】:

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

类似这样的:

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

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

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

【问题讨论】:

  • 查看我刚刚发布的答案,它与您上面包含的假设 sn-p 非常相似。

标签: django django-class-based-views


【解决方案1】:

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

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

【讨论】:

  • 谢谢。我知道这个解决方案,但对我来说它看起来有点丑(
  • 如果我没有穿@MaxKharandziuk 实际上不,这并不紧急,因为TemplateView 继承自提供它的BaseView
  • 我的意思是我更愿意更改我在问题中提到的状态代码:)
  • 也许你可以做一个 Mixin 并在你的 class foobar(TemplateView, FoobarMixin) 中使用它?
【解决方案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 中对此进行了测试。

【讨论】:

  • 好主意。将其放入的最佳方法是什么?如果我想让它有条件而不是一直呈现 403。
【解决方案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"))

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      这是一个老问题,但我在搜索时首先遇到了它。我使用了一个不同的通用视图 (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 是理想的选择。

      【讨论】:

        猜你喜欢
        • 2018-05-28
        • 1970-01-01
        • 2018-07-03
        • 1970-01-01
        • 2014-07-29
        • 2015-09-10
        • 1970-01-01
        • 2012-10-06
        • 2014-06-21
        相关资源
        最近更新 更多