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

Функция просмотра, или, проще говоря, vue , - это функция 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 . Вы, вероятно, там не живете, поэтому вы измените его в своем файле настроек.

Соответствие между адресами и видом

Итак, подведем итог: эта функция просмотра возвращает HTML-страницу, содержащую текущую дату и время. Чтобы отобразить это представление с определенным URL-адресом, необходимо создать конфигурацию URL-адреса . См. Инструкции в разделе Распространение 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>')

Для удобства и поскольку рекомендуется иметь последовательную страницу с ошибкой 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 по умолчанию хорошо работают для большинства веб-приложений, но их можно легко переопределить для особых нужд. Переопределите соответствующие обработчики, как показано ниже, в конфигурации корневого URL-адреса (установка их в другом месте не имеет никакого эффекта).

Представление 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 ©2020 All rights reserved