Пользовательский обработчик Django404 показывает 404, но выдает заголовок 200

StackOverflow https://stackoverflow.com/questions/1812470

  •  06-07-2019
  •  | 
  •  

Вопрос

Я создал пользовательский обработчик 404 для аутентифицированного веб-сайта Django, чтобы избежать утечки информации.

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 , но это принимает только строку в качестве аргумента, а не шаблон, который не является СУХИМ.

И я вручную попытался установить заголовок с помощью:

    response = render_to_response('404.html')
    response['Status'] = "Not Found - 404"
    return response

Тогда заголовок статуса действительно установлен, но браузер по-прежнему отображает значение 200.

У меня нет выбора ..Любой, у кого есть чаевые, пожалуйста, будьте моим героем ...:)

Спасибо и с уважением,

Джерард.

Редактировать:Кстати, я попробовал значение поля status во всех сортировках, но безуспешно: (

Это было полезно?

Решение

Я бы использовал render_to_string и HttpResponseNotFound, например return HttpResponseNotFound(render_to_string('404.html')).

Другие советы

Наконец-то я нашел, почему возвращенный код состояния не сработал.Вместо установки сообщения в заголовке, это просто:

response.status_code = 404

Тем не менее, код, предложенный PiotrLegnica, определенно выигрывает в простоте, удобочитаемости и красоте..Значок все еще стоит ;)

С уважением,

Джерард.

Основываясь на приведенных выше предложениях, вот моя краткая версия 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

Почему бы вам просто не использовать исключение Http404?

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

Для тебя это должно быть просто прекрасно.

Вы могли бы сделать что-то вроде приведенного ниже примера.

В вашем приложении urls.py добавьте:

# 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 добавьте:

# 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)

Секрет кроется в последней строке:статус=404

Надеюсь, это помогло!

Я с нетерпением жду вклада сообщества в этот подход.=)

Вы можете использовать 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)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top