Представления или views — главные составляющие веб-приложений на основе Django. Еще их называют джангистами или вьюхами. Приложение может не взаимодействовать с базой данных, может не использовать шаблоны, но views в нем будут обязательно — приложение должно как-то отвечать на запросы.
В Django используются два вида представлений:
- Представления-функции — view functions
- Представления-классы — class based views
В одном проекте могут одновременно использоваться оба вида. И нельзя сказать, что один вид лучше другого по всем признакам. У обоих есть свои сильные и слабые стороны. В этом уроке разберем их подробнее.
Представления-функции
Представления-функции — простой, но мощный вид представлений. Это обычные функции, которые принимают на входе запрос — объект класса HttpRequest, и возвращают ответ — объект класса HttpResponse или ему подобных.
Так как каждая функция представления получает полную информацию о запросе, ей одной решать, как этот запрос обрабатывать. Например, функция решает, как реагировать на методы HTTP и как обрабатывать параметры запроса:
def login(request):
if request.method == 'GET':
return render(request, 'login_page.html', context={
'username': request.GET['username']
})
elif request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
check_password(username, password)
...
Если представление — это обычная функция, к ней можно применять обычные декораторы. В Django есть несколько полезных. Вот один из них:
from django.views.decorators.http import require_http_methods
@require_http_methods(['GET', 'POST'])
def login(request):
...
Если такая view получит запрос с отличным от указанных методом, то автоматически будет сформирован ответ MethodNotAllowed (код 405).
View function просты концептуально и дают нам полный контроль над обработкой запроса. Это полезно, но заставляет каждый раз писать код вручную или подготавливать библиотеку декораторов, которые упрощают решение типичных задач.
Представления-классы
Все представления этого вида наследуются от класса django.views.View
. Так выглядит код в простейшем случае:
from django.http import HttpResponse
from django.views import View
class IndexView(View):
def get(self, request, *args, **kwargs):
return HttpResponse('Hello, World!')
Метод get
здесь работает как view function. При этом на каждый запрос будет создан новый экземпляр этого класса. Поэтому мы смело можем объявлять в классе методы, которые по ходу выполнения запроса будут менять его состояние.
Регистрируется представление-класс с помощью метода класса as_view
. Выглядит регистрация так:
urlpatterns = [
...
path('', IndexView.as_view()),
...
Представления-классы хороши тем, что дают возможность легко переиспользовать поведение через наследование. Посмотрим на встроенный TemplateView
из модуля django.views.generic.base
в деле:
urlpatterns = [
...
path('', TemplateView.as_view(template_name='index.html')),
...
Нам даже не пришлось наследовать класс. Мы просто использовали готовый — указали при регистрации имя шаблона. Но даже если бы мы унаследовали класс, чтобы передать шаблону данные, то нам бы пришлось переопределить лишь малую часть функциональности класса-предка:
from django.views.generic.base import TemplateView
class HomePageView(TemplateView):
template_name = "home.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['who'] = 'World'
return context
Подобных базовых представлений Django содержит предостаточно. Также хорошо проработаны представления для отображения сущностей из базы данных: отображение списков записей, отображение отдельных записей в детализированной форме. Сказывается направленность Django на решение задач по разработке контентных сайтов.
Представления-классы хорошо подходят для решения повторяющихся задач, так как большая часть из них уже почти решена силами Django.
Самостоятельная работа
- Переделайте
hexlet_django_blog.views.index
с использованиемTemplateView
. View должна наследовать этот класс, а не быть заменена наTemplateView.as_view(…)
- Переделайте
hexlet_django_blog.article.views.index
в класс-потомок отView
. В дальнейшем мы будем расширять этот класс
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.