Django自定义handler404显示404,但给出标题200

时间:2009-11-28 12:56:08

标签: django http-status-code-404

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

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。

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

Thanx和问候,

杰拉德。

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

6 个答案:

答案 0 :(得分:21)

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

答案 1 :(得分:12)

我终于找到了返回状态代码无效的原因。它不是设置标题消息,而是:

response.status_code = 404

尽管如此,PiotrLegnica建议的代码肯定会在简单性,可读性和美感上获胜。徽章仍然存在;)

此致

杰拉德。

答案 2 :(得分:7)

根据上述建议,这是我的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

答案 3 :(得分:2)

为什么不直接使用Http404?

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

那对你来说应该没问题。

答案 4 :(得分:1)

您可以执行以下示例。

进入你的应用程序的urls.py add:

# 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 add:

# 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

希望它有所帮助!

我期待社区对此方法的投入。 =)

答案 5 :(得分:1)

您可以使用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)