Spec-Zone.ru › Django 5.2

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

Функция просмотра, или коротко представление, — это функция 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 lang="en"><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)

Асинхронные представления

Помимо синхронных функций, представления также могут быть асинхронными («асинхронными») функциями, обычно определёнными с помощью синтаксиса Python async def. Django автоматически обнаружит их и запустит в асинхронном контексте. Однако, для получения преимуществ производительности вам потребуется использовать асинхронный сервер на основе ASGI.

Вот пример асинхронного представления:

import datetime
from django.http import HttpResponse


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

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

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

Spec-Zone.ru

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