pythondjangodjango-viewsdjango-errors

How does Django's HttpResponse status differ from status_code?


I am trying to set up some custom errors views in a Django application, but I am encountering something I don't quite understand regarding the way HttpResponse works.

When I return HttpResponse(status=500) Django does not render the 500.html template. However, when I return using status_code HttpResponse(status_code=500), it works.

Here are the steps to my problem:

  1. Set up handler500 = views.handler500
  2. Build handler500 view:
def handler500(request):
    return render(request, '500.html', status=500)
  1. Try and replicate a 500 error:
def cart(request):
    return HttpResponse(status=500)

I am trying to prevent having to refactor hundreds of views in the existing codebase from status=500 to status_code=500. I am worried about breaking something. More importantly, I'm trying to understand the difference between the two.

When I read the Django source code for response.py, it seems that they convert status to status_code anyway within class HttpResponseBase. Any and all advice is greatly appreciated.


Solution

  • Returning HttpResponse(status=500)

    Returning HttpResponse(status=500) just sends the response with HTTP status code 500, but does not trigger a call to the error handler. Please refer to a related question: How does HttpResponse(status=<code>) work in django?

    If you want to replicate a 500 error, the simplest way is to just raise an unhandled exception in your view, e.g.:

    def cart(request):
        raise Exception()
    

    Why returning HttpResponse(status_code=500) do trigger a call to error handler

    HttpResponse __init__() method does not accept the keyword argument status_code. Trying to create an HttpResponse instance by calling HttpResponse(status_code=500) will raise an exception:

    TypeError: init() got an unexpected keyword argument status_code

    and if it is not handled, the error handler (custom if it is set or default otherwise) will be called to handle the exception and render your 500.html page.

    Please refer to the django documentation: https://docs.djangoproject.com/en/4.1/ref/views/#the-500-server-error-view

    Django executes special-case behavior in the case of runtime errors in view code. If a view results in an exception, Django will, by default, call the view django.views.defaults.server_error, which either produces a “Server Error” message or loads and renders the template 500.html if you created it in your root template directory.