Представления на основе классов
Представление — это вызываемый объект, который принимает запрос и возвращает ответ. Это не обязательно должна быть функция: Django содержит примеры классов, которые можно использовать в качестве представлений. Они позволяют структурировать представления и повторно использовать код с помощью наследования и примесей. Кроме того, существуют универсальные представления для задач, о которых мы поговорим позже, но вы можете разработать собственную структуру повторно используемых представлений, подходящую для вашего варианта использования. Полную информацию см. в справочной документации по представлениям на основе классов.
- Введение в представления на основе классов
- Встроенные универсальные представления на основе классов
- Обработка форм с помощью представлений на основе классов
- Использование примесей с представлениями на основе классов
Основные примеры
Django предоставляет базовые классы представлений, подходящие для широкого круга приложений. Все представления наследуются от класса View, который отвечает за связывание представления с URL-адресами, диспетчеризацию по HTTP-методам и другие общие функции. Класс RedirectView выполняет HTTP-перенаправление, а класс TemplateView расширяет базовый класс, добавляя возможность рендеринга шаблона.
Использование в URLconf
Самый прямой способ использовать универсальные представления — создавать их непосредственно в URLconf. Если вам нужно изменить лишь несколько атрибутов представления на основе классов, их можно передать непосредственно при вызове метода as_view():
from django.urls import path
from django.views.generic import TemplateView
urlpatterns = [
path("about/", TemplateView.as_view(template_name="about.html")),
]
Любые аргументы, переданные в as_view(), переопределят атрибуты, заданные в классе. В этом примере мы задаём template_name в TemplateView. Аналогичным образом можно переопределить атрибут url у RedirectView.
Создание подклассов универсальных представлений
Второй, более мощный способ использовать универсальные представления — наследоваться от существующего представления и переопределять в подклассе атрибуты (например, template_name) или методы (например, get_context_data), задавая новые значения или методы. Рассмотрим, например, представление, которое отображает только один шаблон, about.html. Для этого в Django есть универсальное представление — TemplateView. Мы можем создать его подкласс и переопределить имя шаблона:
# some_app/views.py
from django.views.generic import TemplateView
class AboutView(TemplateView):
template_name = "about.html"
Затем нужно добавить это новое представление в URLconf. TemplateView — это класс, а не функция, поэтому вместо него мы указываем в URL метод класса as_view(), который предоставляет для представлений на основе классов точку входа, похожую на функцию:
# urls.py
from django.urls import path
from some_app.views import AboutView
urlpatterns = [
path("about/", AboutView.as_view()),
]
Дополнительные сведения об использовании встроенных универсальных представлений см. в следующем разделе, посвящённом универсальным представлениям на основе классов.
Поддержка других HTTP-методов
Предположим, кто-то хочет обращаться к нашей библиотеке книг по HTTP, используя представления в качестве API. Клиент API будет время от времени подключаться и загружать данные о книгах, опубликованных с момента последнего посещения. Но если с тех пор новых книг не появилось, получение книг из базы данных, формирование полного ответа и отправка его клиенту будут напрасной тратой процессорного времени и пропускной способности. Возможно, предпочтительнее было бы запросить у API дату публикации самой последней книги.
В URLconf мы сопоставляем URL со списочным представлением книг:
from django.urls import path
from books.views import BookListView
urlpatterns = [
path("books/", BookListView.as_view()),
]
А вот само представление:
from django.http import HttpResponse
from django.views.generic import ListView
from books.models import Book
class BookListView(ListView):
model = Book
def head(self, *args, **kwargs):
last_book = self.get_queryset().latest("publication_date")
response = HttpResponse(
# RFC 1123 date format.
headers={
"Last-Modified": last_book.publication_date.strftime(
"%a, %d %b %Y %H:%M:%S GMT"
)
},
)
return response
Если к представлению обращаются с запросом GET, в ответе возвращается список объектов (с использованием шаблона book_list.html). Но если клиент отправляет запрос HEAD, тело ответа пустое, а заголовок Last-Modified указывает, когда была опубликована самая последняя книга. На основании этой информации клиент может решить, загружать ли полный список объектов.
Асинхронные представления на основе классов
Помимо уже рассмотренных синхронных (def) обработчиков методов, подклассы View могут определять асинхронные (async def) обработчики методов, чтобы использовать асинхронный код с помощью await:
import asyncio
from django.http import HttpResponse
from django.views import View
class AsyncView(View):
async def get(self, request, *args, **kwargs):
# Perform io-blocking view logic using await, sleep for example.
await asyncio.sleep(1)
return HttpResponse("Hello async world!")
В одном классе представления все определённые пользователем обработчики методов должны быть либо синхронными — с использованием def, либо асинхронными — с использованием async def. В as_view() будет вызвано исключение ImproperlyConfigured, если смешаны объявления def и async def.
Django автоматически распознаёт асинхронные представления и запускает их в асинхронном контексте. Подробнее об асинхронной поддержке Django и о том, как лучше использовать асинхронные представления, можно прочитать в разделе Асинхронная поддержка.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/6.0/topics/class-based-views/index/