Представления (Views) — Python: Разработка на фреймворке Django
Представления или 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
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
Представления в Django – время создавать!
view, или представление, — это то место, где мы разместим «логику» работы нашего приложения. Оно запросит информацию из модели , которую мы создали ранее, и передаст её в шаблон . Шаблонами мы займёмся в следующей главе. Представления похожи на методы в Python и лишь немногим сложнее того, с чем мы уже сталкивались в главе Введение в Python.
Представления размещаются в файле views.py . Мы добавим свои представления в файл blog/views.py .
blog/views.py
Хорошо, давай откроем этот файл и посмотрим на его содержимое:
from django.shortcuts import render # Create your views here.
Не слишком много кода.
Помнишь, что строки, начинающиеся с символа # — это комментарии? То есть Python не будет пытаться запустить их содержимое.
Простейшее представление может выглядеть следующим образом.
def post_list(request): return render(request, 'blog/post_list.html', <>)
Как ты можешь заметить, мы создали функцию ( def ) с именем post_list , которая принимает request в качестве аргумента и возвращает ( return ) результат работы функции render , которая уже соберёт наш шаблон страницы blog/post_list.html .
Сохрани файл, перейди по адресу http://127.0.0.1:8000/ и посмотри, что у нас получилось.
Другая ошибка! Читаем, что произошло:

Это значит, что, по крайней мере, сервер снова работает, но что-то всё же пошло не так, верно? Не беспокойся, это просто страница с сообщением об ошибке, бояться совершенно нечего! Как и сообщения об ошибках в консоли, такие страницы чрезвычайно полезны. Здесь ты можешь прочесть: TemplateDoesNotExist — такого шаблона не существует. Давай исправим ошибку и создадим шаблон в следующей главе!
results matching » «
No results matching » «
Django View – базовые представления
Представление — это место, где мы размещаем нашу бизнес-логику приложения. Django View — это функция Python, которая используется для выполнения некоторой бизнес-логики и возврата ответа пользователю. Этот ответ может быть HTML-содержимым веб-страницы, перенаправлением или ошибкой 404.
Все функции представления создаются внутри файла views.py приложения Django.
Django View – простой пример
import datetime # Create your views here. from django.http import HttpResponse def index(request): now = datetime.datetime.now() html = "Now time is %s.
" % now return HttpResponse(html) # rendering the template in HttpResponse
Давайте пройдемся по коду.
Во-первых, мы импортируем библиотеку DateTime, которая предоставляет метод для получения текущей даты и времени, а также класс HttpResponse.
Затем мы определяем индекс функции представления, который принимает HTTP-запрос и отвечает на него.
Просмотр вызовов при сопоставлении с URL-адресом в urls.py:
path('index/', views.index),

Возврат ошибок
Django предоставляет различные встроенные классы ошибок, которые являются подклассами HttpResponse и используются для отображения сообщения об ошибке в виде ответа HTTP. Некоторые классы перечислены ниже.
| Класс | Описание |
|---|---|
| HttpResponseNotModified | Он используется для обозначения того, что страница не изменялась с момента последнего запроса пользователя (код состояния 304). |
| HttpResponseBadRequest | Он действует аналогично HttpResponse, но использует код состояния 400. |
| HttpResponseNotFound | Действует так же, как HttpResponse, но использует код состояния 404. |
| HttpResponseNotAllowed | Использует код 410. |
| HttpResponseServerError | Использует код состояния 500. |
from django.shortcuts import render # Create your views here. from django.http import HttpResponse, HttpResponseNotFound def index(request): a = 1 if a: return HttpResponseNotFound('Page not found
') else: return HttpResponse('Page was found
') # rendering the template in HttpResponse

Django View HTTP-декораторы
Декораторы HTTP используются для ограничения доступа к представлению на основе метода запроса.
Эти декораторы перечислены в django.views.decorators.http и возвращают django.http.HttpResponseNotAllowed, если условия не выполняются.
Пример Django Http Decorator:
from django.shortcuts import render # Create your views here. from django.http import HttpResponse, HttpResponseNotFound from django.views.decorators.http import require_http_methods @require_http_methods(["GET"]) def show(request): return HttpResponse('This is Http GET request.
')
Этот метод будет выполняться, только если запрос является запросом HTTP GET.
from django.contrib import admin from django.urls import path from myapp import views urlpatterns = [ path('admin/', admin.site.urls), path('index/', views.index), path('show/', views.show), ]
Базовые виды¶
Следующие три класса обеспечивают большую часть функциональности, необходимой для создания представлений Django. Вы можете рассматривать их как родительские представления, которые могут использоваться сами по себе или наследоваться от них. Они могут не предоставлять всех возможностей, необходимых для проектов, в этом случае существуют Миксины и представления на основе классов Generic.
Многие встроенные в Django представления, основанные на классах, наследуются от других представлений, основанных на классах, или различных миксинов. Поскольку эта цепочка наследования очень важна, классы-предки документируются в разделе Предки (MRO). MRO — это аббревиатура от Method Resolution Order.
View ¶
class django.views.generic.base. View ¶
Базовый класс представления. Все остальные представления, основанные на классе, наследуются от этого базового класса. Он не является строго общим представлением и поэтому может быть импортирован из django.views .
Пример views.py:
from django.http import HttpResponse from django.views import View class MyView(View): def get(self, request, *args, **kwargs): return HttpResponse("Hello, World!")
Пример urls.py:
from django.urls import path from myapp.views import MyView urlpatterns = [ path("mine/", MyView.as_view(), name="my-view"), ]
Атрибуты
Список имен методов HTTP, которые будет принимать это представление.
["get", "post", "put", "patch", "delete", "head", "options", "trace"]
Методы
classmethod as_view ( ** initkwargs )¶
Возвращает вызываемое представление, которое принимает запрос и возвращает ответ:
response = MyView.as_view()(request)
Возвращаемое представление имеет атрибуты view_class и view_initkwargs .
Когда представление вызывается во время цикла запрос/ответ, метод setup() присваивает HttpRequest атрибуту представления request , а любые позиционные и/или ключевые аргументы captured from the URL pattern атрибутам args и kwargs соответственно. Затем вызывается dispatch() .
Если подкласс View определяет асинхронные ( async def ) обработчики методов, as_view() пометит возвращаемый вызываемый метод как функцию coroutine. Если для одного класса представления определены асинхронные ( ImproperlyConfigured ) и синхронные ( async def ) обработчики, будет вызвано исключение def .
Выполняет инициализацию представления ключа перед dispatch() .
Если вы переопределяете этот метод, вы должны вызвать super() .
Часть представления view – метод, который принимает аргумент request плюс аргументы и возвращает HTTP-ответ.
Реализация по умолчанию будет проверять метод HTTP и пытаться делегировать на метод, который соответствует методу HTTP; GET будет делегирован на get() , POST на post() и так далее.
По умолчанию запрос HEAD будет передан методу get() . Если вам нужно обрабатывать запросы HEAD иначе, чем GET , вы можете переопределить метод head() . Пример смотрите в Поддержка других методов HTTP .
http_method_not_allowed ( request , * args , ** kwargs )¶
Если представление было вызвано с помощью метода HTTP, который оно не поддерживает, вместо него вызывается этот метод.
Реализация по умолчанию возвращает HttpResponseNotAllowed со списком разрешенных методов в виде обычного текста.
Обрабатывает ответы на запросы HTTP-глагола OPTIONS. Возвращает ответ с заголовком Allow , содержащим список разрешенных для представления имен HTTP-методов.
Если другие обработчики методов HTTP в классе являются асинхронными ( async def ), то ответ будет обернут в корутинную функцию для использования с await .
TemplateView ¶
class django.views.generic.base. TemplateView ¶
Выполняет рендеринг заданного шаблона с контекстом, содержащим параметры, захваченные в URL.
Предки (MRO)
Это представление наследует методы и атрибуты от следующих представлений:
- django.views.generic.base.TemplateResponseMixin
- django.views.generic.base.ContextMixin
- django.views.generic.base.View
- setup()
- dispatch()
- http_method_not_allowed()
- get_context_data()
Пример views.py:
from django.views.generic.base import TemplateView from articles.models import Article class HomePageView(TemplateView): template_name = "home.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["latest_articles"] = Article.objects.all()[:5] return context
Пример urls.py:
from django.urls import path from myapp.views import HomePageView urlpatterns = [ path("", HomePageView.as_view(), name="home"), ]
Контекст
- Заполняется (через ContextMixin ) аргументами ключевых слов, взятых из шаблона URL, который обслуживал представление.
- Вы также можете добавить контекст, используя аргумент extra_context для ключевого слова as_view() .
RedirectView ¶
class django.views.generic.base. RedirectView ¶
Перенаправляет на заданный URL.
Заданный URL может содержать форматирование строк в стиле словаря, которое будет интерполировано на параметры, переданные в URL. Поскольку интерполяция ключевых слов выполняется всегда (даже если не передано никаких аргументов), любые символы «%» в URL должны быть записаны как «%%» , чтобы Python преобразовал их в один знак процента при выводе.
Если заданный URL равен None , Django вернет HttpResponseGone (410).
Предки (MRO)
Это представление наследует методы и атрибуты от следующего представления:
- setup()
- dispatch()
- http_method_not_allowed()
- get_redirect_url()
Пример views.py:
from django.shortcuts import get_object_or_404 from django.views.generic.base import RedirectView from articles.models import Article class ArticleCounterRedirectView(RedirectView): permanent = False query_string = True pattern_name = "article-detail" def get_redirect_url(self, *args, **kwargs): article = get_object_or_404(Article, pk=kwargs["pk"]) article.update_counter() return super().get_redirect_url(*args, **kwargs)
Пример urls.py:
from django.urls import path from django.views.generic.base import RedirectView from article.views import ArticleCounterRedirectView, ArticleDetailView urlpatterns = [ path( "counter//", ArticleCounterRedirectView.as_view(), name="article-counter", ), path("details//", ArticleDetailView.as_view(), name="article-detail"), path( "go-to-django/", RedirectView.as_view(url="https://www.djangoproject.com/"), name="go-to-django", ), ]
Атрибуты
URL для перенаправления в виде строки. Или None , чтобы выдать ошибку 410 (Ушел) HTTP.
Имя шаблона URL для перенаправления. Перенаправление будет выполняться с использованием тех же args и kwargs, которые были переданы для этого представления.
Должно ли перенаправление быть постоянным. Единственным отличием здесь является возвращаемый код статуса HTTP. Если True , то перенаправление будет использовать код состояния 301. Если False , то перенаправление будет использовать код состояния 302. По умолчанию permanent является False .
Передавать ли строку запроса GET в новое местоположение. Если True , то строка запроса добавляется к URL. Если False , то строка запроса отбрасывается. По умолчанию query_string равно False .
Методы
get_redirect_url ( * args , ** kwargs )¶
Создает целевой URL для перенаправления.
Аргументы args и kwargs являются позиционными и/или ключевыми аргументами captured from the URL pattern , соответственно.
Реализация по умолчанию использует url в качестве начальной строки и выполняет расширение именованных параметров % в этой строке, используя именованные группы, захваченные в URL.
Если url не установлено, get_redirect_url() пытается обратить pattern_name , используя то, что было захвачено в URL (используются как именованные, так и неименованные группы).
При запросе query_string он также добавит строку запроса к сгенерированному URL. Подклассы могут реализовать любое поведение по своему усмотрению, лишь бы метод возвращал готовую к перенаправлению строку URL.