Django custom handler404 shows 404 but gives header 200

后端 未结 6 892
春和景丽
春和景丽 2020-12-15 11:58

I made a custom handler404 for a authenticated Django website to avoid information leakage.

def check_logged_in_404(request):
    \"\"\" Custom 404. Show fr         


        
相关标签:
6条回答
  • 2020-12-15 12:09

    You can use render method:

    from django.shortcuts import render
    

    Returns a HttpResponse whose content is filled with the result of calling django.template.loader.render_to_string() with the passed arguments.

    Uses a RequestContext by default.

    Example:

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

    And with keywords:

    return render(request, '404.html', {'data': 'some data'}, status=404)
    
    0 讨论(0)
  • 2020-12-15 12:12

    I finally found why the returned status code didnt work. Instead of setting a header message, it simply is:

    response.status_code = 404
    

    Nevertheless, the code suggested by PiotrLegnica definitely wins on simplicity, readability and beauty .. The badge still stands ;)

    Regards,

    Gerard.

    0 讨论(0)
  • 2020-12-15 12:19

    Why don't you just use Http404 exception?

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

    That should be just fine for you.

    0 讨论(0)
  • 2020-12-15 12:28

    I'd use render_to_string and HttpResponseNotFound, e.g. return HttpResponseNotFound(render_to_string('404.html')).

    0 讨论(0)
  • 2020-12-15 12:30

    You could do something like the example below.

    Into your application's 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
    

    Into your application's 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)
    

    The secret is in the last line: status=404

    Hope it helped!

    I look forward to see the community inputs to this approach. =)

    0 讨论(0)
  • 2020-12-15 12:36

    Based on suggestions above, here is my short version of 404, 500 handlers:

    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
    
    0 讨论(0)
提交回复
热议问题