El controlador personalizado Django404 muestra 404 pero da el encabezado 200
-
06-07-2019 - |
Pregunta
Hice un controlador personalizado404 para un sitio web autenticado de Django para evitar fugas de información.
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')
Funcionalmente hace exactamente lo que quiero. Sin embargo, la página de retorno 404 tiene un estado 200, que es correcto en cuanto a código. Pero esto obviamente debe ser un estado de retorno 404.
Un raise404 no funciona porque, si no termina en una recursión infinita, vuelve aquí y, por lo tanto, genera el mismo problema.
Probé un HttpResponseNotFound, pero esto solo toma una cadena como argumento y no una plantilla, que no es DRY-ish.
E intenté configurar manualmente el encabezado con:
response = render_to_response('404.html')
response['Status'] = "Not Found - 404"
return response
Entonces el encabezado de estado está configurado pero el navegador aún muestra 200.
Me he quedado sin opciones. Cualquiera que tenga consejos, sé mi héroe ... :)
Gracias y saludos,
Gerard.
Editar : probé el valor del campo de estado en todo tipo por cierto, pero no tuve suerte :(
Solución
Usaría < code> render_to_string y HttpResponseNotFound
, p. ej. return HttpResponseNotFound (render_to_string ('404.html'))
.
Otros consejos
Finalmente descubrí por qué el código de estado devuelto no funcionaba. En lugar de configurar un mensaje de encabezado, simplemente es:
response.status_code = 404
Sin embargo, el código sugerido por PiotrLegnica definitivamente gana en simplicidad, legibilidad y belleza. La insignia sigue en pie;)
Saludos,
Gerard.
Según las sugerencias anteriores, aquí está mi versión corta de 404, 500 controladores:
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
¿Por qué no usas la excepción Http404?
if request.user.is_authenticated():
raise Http404
else:
return HttpResponseRedirect('/login')
Eso debería estar bien para ti.
Podría hacer algo como el ejemplo a continuación.
En urls.py de su aplicación agregue:
# 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'^
En el archivo views.py de su aplicación, agregue:
# 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)
El secreto está en la última línea: status = 404
¡Espero que haya ayudado!
Espero ver las aportaciones de la comunidad a este enfoque. =)
, include('app.homepage.urls')),
)
handler404 = views.error404
En el archivo views.py de su aplicación, agregue:
<*>El secreto está en la última línea: status = 404
¡Espero que haya ayudado!
Espero ver las aportaciones de la comunidad a este enfoque. =)
Puede usar el método render
:
from django.shortcuts import render
Devuelve un HttpResponse cuyo contenido se llena con el resultado de llamando a django.template.loader.render_to_string () con el pasado argumentos.
Utiliza un RequestContext por defecto.
Ejemplo:
return render(request, '404.html', status=404)
Y con palabras clave:
return render(request, '404.html', {'data': 'some data'}, status=404)