Django 5 для начинающих

Прогресс по курсу:  9/1004

2.5 Диспетчер URL, часть 2.
3 из 13 шагов пройдено
0 из 42 баллов  получено

Переадресация и отправка статусных кодов

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

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

Для создания временной переадресации применяется класс HttpResponseRedirect, а для постоянной - класс HttpResponsePermanentRedirect, которые расположены в пакете django.http.

Так, определим в файле views.py следующий код:

from django.http import HttpResponse, HttpResponseRedirect, HttpResponsePermanentRedirect


def index(request):
    return HttpResponse("Index")


def about(request):
    return HttpResponse("About")


def contact(request):
    return HttpResponseRedirect("/about")


def details(request):
    return HttpResponsePermanentRedirect("/")

При обращении к функции contact она будет перенаправлять по пути about, который будет обрабатываться функцией about.
А функция details будет использовать постоянную переадресацию и перенаправлять на корень веб-приложения.


И также в файле urls.py для тестирования определим следующие маршруты:

from django.urls import path
from blog import views

urlpatterns = [
    path("", views.index),
    path("about/", views.about),
    path("contact/", views.contact),
    path("details/", views.details),
]


Запустим сервер и перейдем http://127.0.0.1:8000 и увидим надпись Index, далее откроем адрес http://127.0.0.1:8000/contact/ и нас перенаправит по адресу http://127.0.0.1:8000/about/.

Отправка статусных кодов

Также в пакете django.http есть ряд классов, которые позволяют отправлять определенный статусный код:

Статусный код

Класс

304 (Not Modified)

HttpResponseNotModified

400 (Bad Request)

HttpResponseBadRequest

403 (Forbidden)

HttpResponseForbidden

404 (Not Found)

HttpResponseNotFound

405 (Method Not Allowed)

HttpResponseNotAllowed

410 (Gone)

HttpResponseGone

500 (Internal Server Error)

HttpResponseServerError


В функцию конструктора этих классов можно передать некоторые данные, например, сообщение об ошибке, которое увидит пользователь:

HttpResponseNotModified()
HttpResponseBadRequest("Bad Request")
HttpResponseForbidden("Forbidden")
HttpResponseNotFound("Not Found")
HttpResponseNotAllowed("Method is not allowed")
HttpResponseGone("Content is no longer here")
HttpResponseServerError("Server Error")


Например, определим следующий файл views.py:

from django.http import HttpResponse, HttpResponseNotFound, HttpResponseForbidden, HttpResponseBadRequest


def index(request, id):
    people = [None, "Bob", "Sam", "Tom"]
    # если пользователь найден, возвращаем его
    if id in range(1, len(people)):
        return HttpResponse(people[id])
    # если нет, то возвращаем ошибку 404
    else:
        return HttpResponseNotFound("Not Found")


def access(request, age):
    # если возраст НЕ входит в диапазон 1-110, посылаем ошибку 400
    if age not in range(1, 111):
        return HttpResponseBadRequest("Некорректные данные")
    # если возраст больше 17, то доступ разрешен
    if (age > 17):
        return HttpResponse("Доступ разрешен")
    # если нет, то возвращаем ошибку 403
    else:
        return HttpResponseForbidden("Доступ заблокирован: недостаточно лет")

Функция index принимает параметр id. Это будет индекс элемента в списке people. Однако пользователь может передать и недействительный индекс, например, 100, хотя в примере в списке только 3 элемента. Поэтому, если передан действительный индекс, то возвращаем элемент по этому индексу. Если же индекс недействителен, то с помощью класса HttpResponseNotFound возвращаем ошибку 404 и сообщение об ошибке.

Аналогично функция access принимает параметр age, который представляет условный возраст пользователя. Если возраст выходит за некоторые разумные пределы (1-110), то с помощью класса HttpResponseBadRequest возвращаем ошибку 400. Если возраст укладывается в эти рамки, но он меньше 18, то с помощью класса HttpResponseForbidden возвращаем ошибку 403 о том, что доступ запрещен.

Для теста в файле urls.py определим следующие маршруты:

from django.urls import path
from blog import views

urlpatterns = [
    path("index/<int:id>/", views.index),
    path("access/<int:age>/", views.access),
]


Обратимся к функции index, передав для параметра id корректные и некорректные значения. И в зависимости от значения параметра мы увидим либо данные из списка people, либо ошибку 404:


Аналогично при обращении по адресу /access в зависимости от значения параметра age мы увидим либо сообщения об ошибке, либо обычное сообщение:


Стоит отметить, что статусные сообщения об ошибках также отображаются в консоль запущенного приложения.


  • Комментария
Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий
def index(request, id):
    people = [None, "Bob", "Sam", "Tom"]
    # если пользователь найден, возвращаем его
    if id in range(1, len(people)):
        return HttpResponse(people[id])
    # если нет, то возвращаем ошибку 404
    else:
        return HttpResponseNotFound("Not Found")

Вопросы:
1. Для people не лучше ли будет использовать кортеж в данном примере (вероятнее всего пример тестовый и данные обычно тут должны подтягиваться из БД)?
2. От конструкции else  можно отказаться и оставить просто return HttpResponseNotFound('Not Found'), но как пишут на практике? Питон говорит явное лучше неявного, но довольно часто видел отказ в таких случаях от else...

Что имею ввиду:

def index(request, id):
    people = (None, 'Bob', 'Sam', 'Tom')
    if id in range(1, len(people)):
        return HttpResponse(people[id])
    return HttpResponseNotFound('Not Found')

@Нарбеков_Марсель,

1. да это тестовый пример, если такое используется на практике(жёстко закодированные данные в представлении), то кортеж всегда предпочтительнее списка.

2. оператор else тут для наглядности, на практике так не пишут.

@Дмитрий_Селезнев, Спасибо!

эта ссылка почему-то неправильно открывает, из двух частей состоит

 

@Дмитрий_Чекмасов, исправил, спасибо.