I made a custom handler404 for a authenticated Django website to avoid information leakage.
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')
Functionally it does exactly what I want. However the 404 return page has a status 200, which is correct code-wise. But this obviously needs to be a 404 return status.
A raise404 doesn't work because, if not ending in a infinite recursion, it comes back here and thus results in the same issue.
I tried a HttpResponseNotFound, but this only takes a string as a argument and not a template, which is not to DRY-ish.
And I manually tried to set the header with:
response = render_to_response('404.html')
response['Status'] = "Not Found - 404"
return response
Then the status header is indeed set but the browser still shows up a 200.
I'm out of options .. Anybody that has tips, please be my hero ... :)
Thanx and regards,
Gerard.
Edit: I tried the status field value in all sort btw, but no luck :(
Why don't you just use Http404 exception?
That should be just fine for you.
I finally found why the returned status code didnt work. Instead of setting a header message, it simply is:
Nevertheless, the code suggested by PiotrLegnica definitely wins on simplicity, readability and beauty .. The badge still stands ;)
Regards,
Gerard.
You could do something like the example below.
Into your application's urls.py add:
Into your application's views.py add:
The secret is in the last line: status=404
Hope it helped!
I look forward to see the community inputs to this approach. =)
Based on suggestions above, here is my short version of 404, 500 handlers:
You can use
render
method:Example:
And with keywords:
I'd use
render_to_string
andHttpResponseNotFound
, e.g.return HttpResponseNotFound(render_to_string('404.html'))
.