Spec-Zone.ru › Django 3.0

Создание представлений

Функция представления, или представление вкратце, — это функция Python, которая принимает веб-запрос и возвращает веб-ответ. Этот ответ может быть HTML-содержимым веб-страницы, перенаправлением, ошибкой 404, XML-документом, изображением... или чем угодно. Само представление содержит любую необходимую произвольную логику для возврата этого ответа. Этот код может находиться в любом месте, при условии, что он находится на вашем пути Python. Других требований нет — никакого «волшебства», так сказать. Для размещения кода где-то принято помещать представления в файл под названием views.py, размещённый в каталоге вашего проекта или приложения.

Простое представление

Вот представление, которое возвращает текущую дату и время в виде HTML-документа:

from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

Давайте разберём этот код построчно:

  • Сначала мы импортируем класс HttpResponse из модуля django.http, а также библиотеку Python datetime.
  • Далее, мы определяем функцию под названием current_datetime. Это функция представления. Каждая функция представления принимает объект HttpRequest в качестве первого параметра, который обычно называется request.

    Обратите внимание, что имя функции представления не имеет значения; Django распознаёт её без особых требований к названию. Здесь мы называем её current_datetime, потому что это имя чётко указывает на её назначение.

  • Представление возвращает объект HttpResponse, содержащий сгенерированный ответ. Каждая функция представления отвечает за возвращение объекта HttpResponse. (Есть исключения, но мы рассмотрим их позже.)

Часовой пояс Django

Django включает настройку TIME_ZONE, которая по умолчанию установлена в America/Chicago. Вероятно, это не ваш часовой пояс, поэтому вам может потребоваться изменить его в файле настроек.

Сопоставление URL-адресов с представлениями

Итак, подытожив, эта функция представления возвращает HTML-страницу, содержащую текущую дату и время. Для отображения этого представления по определённому URL-адресу необходимо создать URLconf; см. Диспечер URL-адресов для получения инструкций.

Возвращение ошибок

Django предоставляет средства для возврата кодов ошибок HTTP. Существуют подклассы HttpResponse для ряда распространённых кодов состояния HTTP, отличных от 200 (что означает «ОК»). Полный список доступных подклассов можно найти в документации запрос/ответ. Возвращайте экземпляр одного из этих подклассов вместо обычного объекта HttpResponse, чтобы указать ошибку. Например:

from django.http import HttpResponse, HttpResponseNotFound

def my_view(request):
    # ...
    if foo:
        return HttpResponseNotFound('<h1>Page not found</h1>')
    else:
        return HttpResponse('<h1>Page was found</h1>')

Нет специализированного подкласса для каждого возможного кода ответа HTTP, так как многие из них не будут столь распространены. Однако, как указано в документации HttpResponse, вы также можете передать код состояния HTTP в конструктор HttpResponse, чтобы создать класс возврата для любого кода состояния, который вам нужен. Например:

from django.http import HttpResponse

def my_view(request):
    # ...

    # Return a "created" (201) response code.
    return HttpResponse(status=201)

Поскольку ошибки 404 являются наиболее распространёнными ошибками HTTP, существует более простой способ их обработки.

Исключение Http404

class django.http.Http404

Когда вы возвращаете ошибку, такую как HttpResponseNotFound, вы отвечаете за определение HTML результирующей страницы с ошибкой:

return HttpResponseNotFound('<h1>Page not found</h1>')

Для удобства и потому, что полезно иметь согласованную страницу с ошибкой 404 на вашем сайте, Django предоставляет исключение Http404. Если вы вызовете Http404 в любой точке функции представления, Django перехватит его и вернёт стандартную страницу с ошибкой для вашего приложения, вместе с кодом ошибки HTTP 404.

Пример использования:

from django.http import Http404
from django.shortcuts import render
from polls.models import Poll

def detail(request, poll_id):
    try:
        p = Poll.objects.get(pk=poll_id)
    except Poll.DoesNotExist:
        raise Http404("Poll does not exist")
    return render(request, 'polls/detail.html', {'poll': p})

Чтобы отобразить настраиваемую HTML-страницу, когда Django возвращает 404, можно создать HTML-шаблон с именем 404.html и поместить его в корень вашей структуры шаблонов. Этот шаблон будет затем отображаться, когда DEBUG установлен в False.

Когда DEBUG равен True, вы можете предоставить сообщение для Http404 , и оно отобразится в стандартном отладочном шаблоне 404. Используйте эти сообщения для отладки; они обычно не подходят для использования в шаблон 404 для производства.

Настройка представлений ошибок

По умолчанию представления ошибок Django должны быть достаточными для большинства веб-приложений, но их можно легко переопределить, если вам требуется любое пользовательское поведение. Укажите обработчики, как показано ниже, в вашем URLconf (если вы укажете их где-то ещё, это не повлияет на результат).

Представление page_not_found() переопределяется с помощью handler404:

handler404 = 'mysite.views.my_custom_page_not_found_view'

Представление server_error() переопределяется с помощью handler500:

handler500 = 'mysite.views.my_custom_error_view'

Представление permission_denied() переопределяется с помощью handler403:

handler403 = 'mysite.views.my_custom_permission_denied_view'

Представление bad_request() переопределяется с помощью handler400:

handler400 = 'mysite.views.my_custom_bad_request_view'

См. также

Используйте настройку CSRF_FAILURE_VIEW для переопределения представления ошибки CSRF.

Тестирование настраиваемых представлений ошибок

Чтобы проверить ответ пользовательского обработчика ошибок, вызовите соответствующее исключение в тестовом представлении. Например:

from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
from django.test import SimpleTestCase, override_settings
from django.urls import path


def response_error_handler(request, exception=None):
    return HttpResponse('Error handler content', status=403)


def permission_denied_view(request):
    raise PermissionDenied


urlpatterns = [
    path('403/', permission_denied_view),
]

handler403 = response_error_handler


# ROOT_URLCONF must specify the module that contains handler403 = ...
@override_settings(ROOT_URLCONF=__name__)
class CustomErrorHandlerTests(SimpleTestCase):

    def test_handler_renders_template_response(self):
        response = self.client.get('/403/')
        # Make assertions on the response here. For example:
        self.assertContains(response, 'Error handler content', status_code=403)

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/3.0/topics/http/views/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API