Написание просмотров

Функция просмотра или вид для краткости, является функцией 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модуля вместе с datetimeбиблиотекой Python .

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

    Обратите внимание, что имя функции просмотра не имеет значения; его не нужно называть определенным образом, чтобы Django мог его распознать. Мы называем это current_datetimeздесь, потому что это имя ясно указывает на то, что он делает.

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

Часовой пояс Джанго

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Исключение

класс django.http.Http404

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

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

Django предоставляет Http404исключение для удобства и потому, что это хорошая идея, чтобы на вашем сайте была согласованная страница с ошибкой 404 . Если вы вызовете 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 3.1.

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

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

import datetime
from django.http import HttpResponse

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

Вы можете узнать больше о поддержке асинхронного режима в Django и о том, как лучше всего использовать асинхронные представления, в разделе «Поддержка асинхронного режима» .

Copyright ©2021 All rights reserved