【问题标题】:Django custom handler404 shows 404 but gives header 200Django 自定义 handler404 显示 404 但给出标头 200
【发布时间】:2010-12-21 05:06:45
【问题描述】:

我为经过身份验证的 Django 网站制作了一个自定义 handler404,以避免信息泄露。

def check_logged_in_404(request):
    """ Custom 404. Show friendly 404 when logged in and redirect to /login
    when not logged in.
    """
    if request.user.is_authenticated():
        return render_to_response('404.html')
    else:
        return HttpResponseRedirect('/login')

从功能上讲,它完全符合我的要求。但是,404 返回页面的状态为 200,这在代码方面是正确的。但这显然需要是404返回状态。

raise404 不起作用,因为如果不是以无限递归结束,它会回到这里并因此导致相同的问题。

我尝试了一个 HttpResponseNotFound,但这只接受一个字符串作为参数,而不是一个模板,这不是 DRY-ish。

我手动尝试设置标题:

    response = render_to_response('404.html')
    response['Status'] = "Not Found - 404"
    return response

然后确实设置了状态标题,但浏览器仍然显示 200。

我别无选择..任何有提示的人,请成为我的英雄...:)

感谢和问候,

杰拉德。

编辑:我尝试了所有排序的状态字段值,但没有运气:(

【问题讨论】:

  • 你无法相信这对我造成了多大的伤害

标签: django http-status-code-404


【解决方案1】:

我会使用 render_to_stringHttpResponseNotFound,例如return HttpResponseNotFound(render_to_string('404.html')).

【讨论】:

  • 嗯没有意识到“render_to_string”。仍然好奇为什么设置的状态代码不被尊重。无论如何......你肯定赢得了“某人的英雄”徽章......;)......非常感谢!
【解决方案2】:

我终于找到了为什么返回的状态码不起作用。而不是设置标题消息,它只是:

response.status_code = 404

尽管如此,PiotrLegnica 建议的代码在简单性、可读性和美观方面绝对胜出 .. 徽章仍然存在 ;)

问候,

杰拉德。

【讨论】:

    【解决方案3】:

    根据上述建议,这是我的 404、500 处理程序的简短版本:

    def handler404(request):
        response = render_to_response('404.html', {},
                                      context_instance=RequestContext(request))
        response.status_code = 404
        return response
    
    
    def handler500(request):
        response = render_to_response('500.html', {},
                                      context_instance=RequestContext(request))
        response.status_code = 500
        return response
    

    【讨论】:

    • 这个答案是最容易实现的,不需要任何 cusotm urls.py 配置。
    【解决方案4】:

    为什么不直接使用 Http404 异常?

    if request.user.is_authenticated():
        raise Http404
    else:
        return HttpResponseRedirect('/login')
    

    这对你来说应该没问题。

    【讨论】:

    • 在提升 Http404 时不知何故我得到了 500 响应。尽管如此,我认为函数内部需要有区别,否则我最终会出现递归错误,或者我需要编写一个 page_not_found() 视图。无论如何,谢谢。
    • 你从django.http导入Http404了吗?
    • Emphh,当你提出它时,你会被重定向到你的 404 处理程序。有些人希望它们是定制的。
    • 我在使用raise Http404时仍然得到状态200
    【解决方案5】:

    你可以使用render方法:

    from django.shortcuts import render
    

    返回一个 HttpResponse,其内容填充了 使用传递的调用 django.template.loader.render_to_string() 论据。

    默认使用 RequestContext。

    例子:

    return render(request, '404.html', status=404)
    

    还有关键字:

    return render(request, '404.html', {'data': 'some data'}, status=404)
    

    【讨论】:

      【解决方案6】:

      你可以像下面的例子那样做。

      在你的应用程序的 urls.py 中添加:

      # Imports
      from django.conf.urls.static import static
      from django.conf.urls import handler404
      from django.conf.urls import patterns, include, url
      from yourapplication import views
      
      ##
      # Handles the URLS calls
      urlpatterns = patterns('',
          # url(r'^$', include('app.homepage.urls')),
      )
      
      handler404 = views.error404
      

      进入你应用的views.py添加:

      # Imports
      from django.shortcuts import render
      from django.http import HttpResponse
      from django.template import Context, loader
      
      
      ##
      # Handle 404 Errors
      # @param request WSGIRequest list with all HTTP Request
      def error404(request):
      
          # 1. Load models for this view
          #from idgsupply.models import My404Method
      
          # 2. Generate Content for this view
          template = loader.get_template('404.htm')
          context = Context({
              'message': 'All: %s' % request,
              })
      
          # 3. Return Template for this view + Data
          return HttpResponse(content=template.render(context), content_type='text/html; charset=utf-8', status=404)
      

      秘密在最后一行:status=404

      希望对您有所帮助!

      我期待看到社区对这种方法的投入。 =)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-23
        • 2021-03-23
        • 2019-09-14
        • 2016-05-11
        • 1970-01-01
        • 2011-06-22
        相关资源
        最近更新 更多