Пользовательский обработчик Django404 показывает 404, но дает заголовок 200 - PullRequest
8 голосов
/ 28 ноября 2009

Я создал собственный обработчик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.

Повышение404 не работает, потому что, если оно не заканчивается бесконечной рекурсией, оно возвращается сюда и, следовательно, приводит к той же проблеме.

Я попробовал HttpResponseNotFound, но он принимает в качестве аргумента только строку, а не шаблон, что не относится к DRY-ишу.

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

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

Тогда заголовок статуса действительно установлен, но браузер все еще показывает 200.

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

Спасибо и всего наилучшего,

Gerard.

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

Ответы [ 6 ]

21 голосов
/ 28 ноября 2009

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

12 голосов
/ 28 ноября 2009

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

response.status_code = 404

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

С уважением,

Gerard.

7 голосов
/ 02 августа 2013

Исходя из приведенных выше предложений, вот моя короткая версия из 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
2 голосов
/ 28 ноября 2009

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

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

Это должно быть хорошо для тебя.

1 голос
/ 03 февраля 2015

Вы можете использовать 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)
1 голос
/ 26 апреля 2013

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

В URL вашего приложения добавьте:

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...