Spec-Zone.ru › Django 2.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><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-адресов для получения инструкций.

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

Возвращение кодов ошибок HTTP в Django очень просто. Существуют подклассы 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/2.2/topics/http/views/

Spec-Zone.ru

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