Какие функции выполняет файл views py
Следующие три класса реализуют достаточный набор функциональности, чтобы создать представление Django. Вы можете рассматривать их как родительские представления, которые можно использовать как непосредственно, так и в наследовании. Конечно, эти классы не всегда могут удовлетворить все требования к представлению в проекте: в таком случае рекомендуется «присмотреться» к примесям(Mixins) и общим представлениям классам(Generic class-based views)
Множество из встроенных CBV в Django наследуют другие представления-классы или классы-примеси. Это цепочка наследований(и порядок классов) очень важна, поэтому информация о классах-предках находится в разделе Ancestors (MRO). MRO - это акроним для Method Resolution Order.
Самый главный класс в CBV. Все остальные представления-классы наследуются от него. Может быть импортирован из django.views .
Диаграмма методов
Пример views.py:
Пример urls.py:
Атрибуты
Значения по умолчанию:
Методы
classmethod as_view ( ** initkwargs )¶
Возвращает выполняемое(callable) представление, которое принимает запрос и возвращает ответ:
Возвращаемое представление содержит атрибуты view_class и view_initkwargs .
Initializes view instance attributes: self.request , self.args , and self.kwargs prior to dispatch() .
Overriding this method allows mixins to setup instance attributes for reuse in child classes. When overriding this method, you must call super() .
TemplateView ¶
Обрабатывает заданный шаблон, используя контекст(context), содержащий параметры из URL.
Классы-предки, Ancestors (MRO)
Представление наследует методы и атрибуты из следующего представления:
Диаграмма методов
Пример views.py:
Пример urls.py:
Контекст(Context)
- Словарь ключевых аргументов, «отловленных» (через ContextMixin ) из шаблона URL, который обрабатывается данным представлением.
- Вы можете добавить контекст, используя аргумент extra_context для метода as_view() .
RedirectView ¶
Редирект на заданный URL.
Переданный URL может содержать строку с форматированием (dictionary-style), которая будет обработана в соответствии с параметрами «отловленными» в URL. Поскольку ключевая интерполяция всегда выполняется (даже если не было передано никаких аргументов), любые символы "%" в URL должны быть написаны как "%%" , а затем Python преобразует их в один знак процента на выходе.
Классы-предки, Ancestors (MRO)
Представление наследует методы и атрибуты из следующего представления:
Диаграмма методов
Пример views.py:
Пример urls.py:
Атрибуты
Название URL-шаблона на который перенаправлять. Вычисление URL-а будет выполнено с аргументами, переданными в это представление.
Передавать ли строку GET запроса в новую локацию. Если True ,то строка запроса добавляется к URL. Если False , то строка запроса отбрасывается. По умолчанию, query_string равно False .
Методы
get_redirect_url ( * args , ** kwargs )¶
Создает целевой URL для редиректа
Реализация по умолчанию использует url в качестве отправной строки, выполняет подстановку % параметров в этой строке из именованных параметров, полученных из URL.
Если url не указан, get_redirect_url() пытается получить URL по pattern_name , используя «отловленные» параметры из URL (именованные и позиционные).
Если указан атрибут query_string , GET параметры будут добавлены к сгенерированному URL. Подклассы могут реализовать любое поведение, важно лишь чтобы метод возвращал корректную строку URL для редиректа.
В проекте Visual Studio имеются только компоненты на уровне сайта проекта Django, с помощью которых можно выполнить одно или несколько приложений Django. Следующий шаг — создание первого одностраничного приложения.
На этом шаге вы научитесь делать следующее:
- Создание одностраничного приложения Django (шаг 2–1).
- Запуск приложения из проекта Django (шаг 2–2).
- Преобразование представления с помощью HTML (шаг 2–3).
- Преобразование представления с помощью шаблона страницы Django (шаг 2–4).
Шаг 2-1. Создание приложения со стандартной структурой
Приложение Django обычно начинается со стандартного набора файлов. Visual Studio предоставляет шаблоны элемента для запуска приложения Django в проекте Django, а также интегрированную команду меню, которая выполняет ту же функцию.
Шаблоны. В обозревателе решений щелкните проект правой кнопкой мыши и выберите Добавить > Новый элемент. В диалоговом окне Добавить новый элемент выберите шаблон Приложение Django 1.9, укажите имя приложения в поле Имя и нажмите кнопку OК.
Встроенная команда. В обозревателе решений щелкните проект правой кнопкой мыши и выберите Добавить > Приложение Django. Эта команда запрашивает имя и создает приложение Django 1.9.
Создайте приложение с именем HelloDjangoApp, используя любой из методов. В результате будет создана папка в проекте с тем же именем, которая содержит элементы, как описано в указанной ниже таблице.
При использовании имени HelloDjangoApp файл app.py имеет следующее содержимое:
Вопрос. Отличается ли создание приложения Django в Visual Studio от создания приложения в командной строке?
Ответ. Если выполнить команду Добавить > Приложение Django или Добавить > Новый элемент в шаблоне приложения Django, будут созданы те же файлы, что и при использовании команды Django manage.py startapp <app_name> . Преимуществом создания приложения в Visual Studio является то, что папка приложения и все ее файлы автоматически интегрируются в проект. С помощью той же команды Visual Studio можно создать любое количество приложений в проекте.
Шаг 2-2. Запуск приложения из проекта Django
Теперь, если вы снова запустите проект в Visual Studio (используя кнопку панели инструментов или выполнив команды Отладка > Начать отладку), отобразится страница по умолчанию. Содержимое приложения не отобразится, так как для этого необходимо определить страницу приложения и добавить приложение в проект Django.
В папке HelloDjangoApp измените значение views.py в соответствии с кодом ниже, который определяет представление с именем index:
В папке BasicProject (созданной в шаге 1) измените значение urls.py, чтобы оно по крайней мере соответствовало следующему коду (при необходимости можно оставить полезные комментарии):
Фиксация в системе управления версиями
Так как вы внесли изменения в код и успешно их протестировали, пришло время просмотреть и зафиксировать изменения в системе управления версиями. В дальнейших шагах этой статьи указано соответствующее время для повторной фиксации изменений в системе управления версиями, после чего необходимо будет вернуться к этому разделу.
Вопрос. Что означает префикс r перед строками маршрутизации?
Ответ. Префикс r в строке Python означает raw (без обработки). Это предписывает Python не использовать escape-символы в строке. Так как в регулярных выражениях используется множество специальных символов, использование префикса r значительно упрощает чтение этих строк по сравнению с тем, если бы они содержали определенное количество escape-символов \.
Вопрос. Что означают символы ^ и $ в записях маршрутизации URL-адреса?
Если вы не используете в конце регулярного выражения символ $, как в случае с ^home , то шаблон URL-адреса соответствует любому URL-адресу, который начинается с home, например home, homework, homestead и home192837.
Шаг 2-3. Преобразование представления с помощью HTML
Чтобы быстро остановить и перезапустить проект, выполните команду меню Отладка > Перезапустить (CTRL+SHIFT+F5) или нажмите кнопку Перезапуск на панели инструментов отладки:
Шаг 2-4. Преобразование представления с помощью шаблона страницы
Создание HTML в коде работает нормально для маленьких страниц. Однако по мере усложнения страниц обычно нужно сохранить статические части HTML своей страницы (вместе с ссылками на файлы CSS и JavaScript) в качестве ее шаблонов, в которые вы затем вставите динамическое содержимое, созданное в коде. В предыдущем разделе только дата и время вызова now.strftime являлись динамическими. Это значит, что остальное содержимое можно поместить в шаблон страницы.
Шаблон страницы Django — это блок HTML-кода, содержащий любое количество маркеров замены, которые называются переменными. Они разделены > , как и в > . Затем модуль шаблонов Django заменяет переменные динамическим содержимым, предоставленным в коде.
В следующих шагах показано использование шаблонов страницы.
В папке BasicProject, содержащей проект Django, откройте файл settings.py и добавьте имя приложения HelloDjangoApp в список INSTALLED_APPS . Добавление приложения в список указывает проекту Django, что в приложении уже есть папка с идентичным именем.
Кроме того, в settings.py убедитесь в том, что объект TEMPLATES содержит следующую строку (включена по умолчанию), которая указывает Django, что нужно найти шаблоны в папке templates установленного приложения:
В папке HelloDjangoApp откройте файл шаблона страницы templates/HelloDjangoApp/index.html (или templates/index.html в Visual Studio 2017 15.7 и более ранних версий), чтобы увидеть, что в нем находится только одна переменная > :
В папке HelloDjangoApp откройте views.py и замените функцию index приведенным ниже кодом, в котором используется вспомогательная функция django.shortcuts.render . Вспомогательная функция render предоставляет упрощенный интерфейс для работы с шаблонами страницы. Не забудьте сохранить все имеющиеся операторы from .
Первый аргумент в render , как можно увидеть, — это объект запроса, за которым следует относительный путь к файлу шаблона в папке templates приложения. Файл шаблона называется в соответствии с поддерживаемым представлением, если это уместно. Третий аргумент в render представляет собой словарь переменных, к которым относится шаблон. Вы можете добавить объект в словарь. В этом случае переменная в шаблоне может ссылаться на > .
Обратите внимание, что HTML, используемый в свойстве content , отображается только в качестве обычного текста, так как функция render автоматически экранирует этот HTML. Автоматическое экранирование предотвращает случайные уязвимости в отношении атак путем внедрения кода: разработчики часто собирают входные данные с одной страницы и используют их в качестве значения на другой странице с помощью заполнителя шаблона. Экранирование служит напоминанием о том, что HTML-код рекомендуется хранить в шаблоне страницы, а не в коде. К счастью, создание дополнительных переменных при необходимости не представляет трудностей. Например, измените index.html с шаблонами в соответствии со следующими исправлениями, в которых добавлен заголовок страницы и сохранено все форматирование в шаблоне страницы:
Затем запишите функцию представления index указанным ниже образом, чтобы предоставить значения для всех переменных в шаблоне страницы.
Остановите сервер и перезапустите проект. Вы можете заметить, что теперь страница отображается должным образом.
Visual Studio 2017 версии 15.7 или более ранних версий. В качестве завершающего этапа переместите шаблоны в подпапку, имя которой совпадает с именем приложения, которое создает пространство имен и позволяет избежать возможных конфликтов с другими приложениями, добавленными в проект. (Шаблоны в Visual Studio 2017 15.8+ делают это автоматически.) Другими словами, создайте вложенную папку в templates с именем HelloDjangoApp, переместите файл index.html в эту вложенную папку и измените функцию представления index так, чтобы она ссылалась на новый путь шаблона HelloDjangoApp/index.html. Затем запустите проект, убедитесь, что страница отображается должным образом и остановите сервер.
Зафиксируйте изменения в системе управления версиями и обновите удаленный репозиторий при необходимости, как описано в шаге 2–2.
Вопрос. Следует ли хранить шаблоны страницы в отдельном файле?
Ответ. Хотя шаблоны обычно хранятся в отдельных HTML-файлах, вы также можете использовать встроенный шаблон. Чтобы сохранить четкое разделение между исправлением и кодом, рекомендуется использовать отдельный файл.
Вопрос. Следует ли использовать в шаблонах расширение файлов HTML?
Ответ. Использовать расширение .html для файлов шаблона страницы совсем необязательно, так как вы всегда определяете точный относительный путь к файлу во втором аргументе функции render . Однако Visual Studio (и другие редакторы) обычно предоставляет такие функции, как завершение кода или разметка синтаксиса, для файлов HTML, что значительно важнее того, что шаблоны страниц не имеют строгого формата HTML.
На самом деле при работе с проектом Django Visual Studio автоматически обнаруживает, если HTML-файл, который вы редактируете, фактически является шаблоном Django, и предоставляет несколько функций с автоматическим завершением. Например, когда вы начинаете вводить комментарий шаблона страницы Django, . В командах Закомментировать выделенный фрагмент и Раскомментировать выделенный фрагмент (в меню Изменить > Дополнительно или на панели инструментов) также используются комментарии шаблона, а не HTML.
Вопрос. При запуске проекта отображается ошибка, что шаблон не найден. В чем проблема?
Вопрос. Почему организация пространства имен шаблона важна?
Ответ. Когда платформа Django выполняет поиск шаблона, упомянутого в функции render , она использует первый найденный файл, который соответствует относительному пути. Если у вас есть несколько приложений Django в одном проекте, использующие одну структуру папок для шаблонов, скорее всего, одно приложение будет непреднамеренно использовать шаблон из другого приложения. Чтобы избежать подобных ошибок, всегда создавайте вложенную папку в папке templates приложения, которая соответствует имени приложения. Это позволит избежать любого дублирования.
В первой статье о Django мы отвечаем на вопрос «Что такое Django?» и даём обзор того, что делает его особенным. Мы опишем основные функции, в том числе некоторые из расширенных функций, которые у нас не будет времени подробно рассмотреть в этом модуле. Мы также покажем вам некоторые основные строительные блоки приложения Django (хотя на данный момент у вас ещё не будет среды разработки для тестирования).
Требования: | Базовая компьютерная грамотность. Общее понимание server-side website programming, и в частности, механики client-server interactions in websites. |
---|---|
Задача: | Узнать, что такое Django, какие функции он предоставляет, и основные строительные блоки приложения Django. |
Что такое Django?
Django — это высокоуровневый Python веб-фреймворк, который позволяет быстро создавать безопасные и поддерживаемые веб-сайты. Созданный опытными разработчиками, Django берёт на себя большую часть хлопот веб-разработки, поэтому вы можете сосредоточиться на написании своего веб-приложения без необходимости изобретать велосипед. Он бесплатный и с открытым исходным кодом, имеет растущее и активное сообщество, отличную документацию и множество вариантов как бесплатной, так и платной поддержки.
Django помогает писать программное обеспечение, которое будет:
Полным Django следует философии «Всё включено» и предоставляет почти всё, что разработчики могут захотеть сделать «из коробки». Поскольку всё, что вам нужно, является частью единого «продукта», всё это безупречно работает вместе, соответствует последовательным принципам проектирования и имеет обширную и актуальную документацию. Разносторонним Django может быть (и был) использован для создания практически любого типа веб-сайтов — от систем управления контентом и wiki до социальных сетей и новостных сайтов. Он может работать с любой клиентской средой и может доставлять контент практически в любом формате (включая HTML, RSS-каналы, JSON, XML и т. д.). Сайт, который вы сейчас читаете, создан с помощью Django! Хотя Django предоставляет решения практически для любой функциональности, которая вам может понадобиться (например, для нескольких популярных баз данных, шаблонизаторов и т. д.), внутренне он также может быть расширен сторонними компонентами, если это необходимо. Безопасным Django помогает разработчикам избежать многих распространённых ошибок безопасности, предоставляя фреймворк, разработанный чтобы «делать правильные вещи» для автоматической защиты сайта. Например, Django предоставляет безопасный способ управления учётными записями пользователей и паролями, избегая распространённых ошибок, таких как размещение информации о сеансе в файлы cookie, где она уязвима (вместо этого файлы cookie содержат только ключ, а фактические данные хранятся в базе данных) или непосредственное хранение паролей вместо хэша пароля. Хэш пароля — это значение фиксированной длины, созданное путём обработки пароля через криптографическую хэш-функцию. Django может проверить правильность введённого пароля, пропустив его через хэш-функцию и сравнив вывод с сохранённым значением хэша. Благодаря «одностороннему» характеру функции, даже если сохранённое хэш-значение скомпрометировано, злоумышленнику будет сложно определить исходный пароль. Django, по умолчанию, обеспечивает защиту от многих уязвимостей, включая SQL-инъекцию, межсайтовый скриптинг, подделку межсайтовых запросов и кликджекинг (см. Website security для получения дополнительной информации об этих атаках). Масштабируемым Django использует компонентную “shared-nothing” архитектуру (каждая её часть независима от других и, следовательно, может быть заменена или изменена, если это необходимо). Чёткое разделение частей означает, что Django может масштабироваться при увеличении трафика, путём добавления оборудования на любом уровне: серверы кеширования, серверы баз данных или серверы приложений. Одни из самых загруженных сайтов успешно масштабировали Django (например, Instagram и Disqus, если назвать только два из них). Удобным в сопровождении Код Django написан с использованием принципов и шаблонов проектирования, которые поощряют создание поддерживаемого и повторно используемого кода. В частности, в нём используется принцип «Don't Repeat Yourself» (DRY, «не повторяйся»), поэтому нет ненужного дублирования, что сокращает объём кода. Django также способствует группированию связанных функциональных возможностей в повторно используемые «приложения» и, на более низком уровне, группирует связанный код в модули (в соответствии с шаблоном Model View Controller (MVC)). Переносным Django написан на Python, который работает на многих платформах. Это означает, что вы не привязаны к какой-либо конкретной серверной платформе и можете запускать приложения на многих версиях Linux, Windows и Mac OS X. Кроме того, Django хорошо поддерживается многими веб-хостингами, которые часто предоставляют определённую инфраструктуру и документацию для размещения сайтов Django.
Как он появился?
Django был разработан в период с 2003 по 2005 год командой, которая занималась созданием и обслуживанием газетных веб-сайтов. После создания нескольких сайтов, команда начала повторно использовать множество общего кода и шаблонов проектирования. Этот общий код эволюционировал в веб-фреймворк, который превратился в проект "Django" с открытым исходным кодом в июле 2005 года.
Django продолжает расти и улучшаться с момента его первого релиза (1.0) в сентябре 2008 года до недавно выпущенной версии 3.1 (2020). В каждой версии добавлены новые функциональные возможности и исправлены ошибки, начиная от поддержки новых типов баз данных, шаблонизаторов и кеширования, до добавления «общих» функций просмотра и классов (уменьшающих объём кода, который разработчики должны писать для ряда программных задач).
Примечание: Ознакомьтесь с примечаниями к версии на сайте Django, чтобы увидеть что изменилось в последних версиях и как много работы было проделано, чтобы улучшить Django.
Django — это процветающий совместный проект с открытым исходным кодом, в котором заняты многие тысячи пользователей и участников. Несмотря на то, что у него всё ещё есть некоторые особенности, которые отражают его происхождение, Django превратился в универсальный фреймворк, способный разрабатывать веб-сайты любого типа.
Насколько популярен Django?
Нет никаких доступных и окончательных оценок популярности серверных фреймворков (хотя сайты наподобие Hot Framework и пытаются оценить популярность, используя такие механизмы, как подсчёт количества проектов на GitHub и вопросов на StackOverflow для каждой платформы). Лучший вопрос — «достаточно ли Django популярен», чтобы избежать проблем непопулярных платформ. Продолжает ли он развиваться? Можете ли вы получить помощь, если вам нужно? Найдёте ли вы оплачиваемую работу, если изучите Django?
Основываясь на количестве крупных сайтов, которые используют Django, количестве участников и количестве людей, предоставляющих как бесплатную, так и платную поддержку, можно ответить: да, Django — популярный фреймворк!
Django используют такие крупные сайты, как Disqus, Instagram, Knight Foundation, MacArthur Foundation, Mozilla, National Geographic, Open Knowledge Foundation, Pinterest и Open Stack (источник: обзорная страница Django).
Является ли Django гибким?
Веб-фреймворки часто можно поделить на "гибкие" и "негибкие".
Негибкие - это те, у которых есть "правильный путь" для решения какой-либо конкретной задачи. Они часто поддерживают быстрое развёртывание в определённой области (решение проблем определённого типа), потому что правильный способ сделать что-либо обычно хорошо понимается и хорошо документируется. Однако они могут быть менее гибкими при решении проблем за пределами их основной сферы и, как правило, предлагают меньше вариантов того, какие компоненты и подходы они могут использовать.
Напротив, у гибких фреймворков гораздо меньше ограничений на лучший способ склеивания компонентов для достижения цели или даже того, какие компоненты следует использовать. Они облегчают разработчикам использование наиболее подходящих инструментов для выполнения конкретной задачи, хотя и за счёт того, что вам нужно самим найти эти компоненты.
Django «умеренно гибкий» и, следовательно, обеспечивает «лучшее из обоих миров». Он предоставляет набор компонентов для обработки большинства задач веб-разработки и один (или два) предпочтительных способа их использования. Однако такая архитектура Django означает, что вы обычно можете выбирать из нескольких различных опций или при необходимости добавлять поддержку для совершенно новых.
Как выглядит код Django?
Веб-приложения, написанные на Django, обычно группируют код, который обрабатывает каждый из этих шагов, в отдельные файлы:
Примечание: Django реализует уровневую архитектуру "Model View Template (MVT)". Она имеет много общего с более известной архитектурой Model View Controller.
Следующие разделы дадут вам понимание того, как выглядят основные части Django (мы их изучим более детально чуть позже на курсе, когда будет настраивать окружение разработчика).
Отправка запроса в правильное view (urls.py)
Объект urlpatterns является списком функций path() и/или re_path() (в Python списки определяются с помощью квадратных скобок, внутри которых элементы разделены запятыми и могут содержать необязательную завершающую запятую. Например: [item1, item2, item3,] ).
Первый аргумент в обоих методах - маршрут (шаблон), который будет сопоставлен. В методе path() угловые скобки используются для определения частей URL-адреса, которые будут захвачены и переданы в функцию отображения (view) в качестве именованных аргументов. Функция re_path() использует гибкий подход к сопоставлению с шаблоном, известный как регулярное выражение. Мы поговорим об этом в следующей статье!
Второй аргумент — это ещё одна функция, которая будет вызываться при сопоставлении шаблона. Обозначение views.book_detail указывает, что функция называется book_detail() и может быть обнаружена в модуле с именем views (т.е. внутри файла с именем views.py ).
Обработка запроса (views.py)
Примечание: Немного Python:
Отображения (view) обычно содержатся в файле views.py.
Определение данных модели (models.py)
Веб-приложения Django обрабатывают и запрашивают данные через объекты Python, называемые моделями. Модели определяют структуру хранимых данных, включая типы полей и, возможно, их максимальный размер, значения по умолчанию, параметры списка выбора, текст справки для документации, текст меток для форм и т. д. Определение модели не зависит от используемой базы данных — ваши модели будут работать в любой из них. После того как вы выбрали базу данных, которую хотите использовать, вам не нужно напрямую обращаться к ней — вы просто пишете свою структуру модели и другой код, а Django выполняет всю «грязную работу» по обращению к базе данных за вас.
В приведённом ниже фрагменте кода показана очень простая модель Django для объекта Team . Класс Team наследуется от класса models.Model . Он определяет имя команды и командный уровень в качестве полей символов и задаёт максимальное количество символов, которые могут быть сохранены для каждой записи. Team_level может быть одним из нескольких значений, поэтому мы определяем его как поле выбора и предоставляем сопоставление между отображаемыми вариантами и хранимыми данными вместе со значением по умолчанию.
Примечание: Немного Python:
-
Python поддерживает «объектно-ориентированное программирование», то есть стиль программирования, в котором мы организуем наш код в объекты, которые включают связанные данные и функции для работы с этими данными. Объекты также могут наследовать / расширять / выводить из других объектов, позволяя использовать одинаковое поведение между связанными объектами. В Python мы используем ключевое слово class , чтобы определить «скелет» для объекта. Мы можем создать несколько конкретных экземпляров типа объекта на основе модели в классе.
Запросы данных (views.py)
Модель Django предоставляет простой API запросов для поиска в базе данных. Поиск может осуществляться по нескольким полям одновременно, используя различные критерии (такие как exact («точный»), case-insensitive («без учёта регистра»), greater than («больше чем») и т. д.), и может поддерживать сложные выражения (например, вы можете указать поиск в командах U11, у которых есть имя команды, начинающееся с «Fr» или заканчивается на «al»).
Фрагмент кода показывает функцию view (обработчик ресурсов) для отображения всех команд U09. Выделенная жирным строка показывает, как мы можем использовать модель API-запросов для того, чтобы отфильтровать все записи, где поле team_level в точности содержит текст 'U09' (обратите внимание, как эти критерии передаются функции filter() в качестве аргумента с именем поля и типом соответствия, разделённым двойным подчёркиванием: team_level__exact).
Вывод данных (HTML-шаблоны)
Системы шаблонов позволяют указать структуру выходного документа, используя заполнители для данных, которые будут вставлены при генерировании страницы. Шаблоны часто используются для создания HTML, но также могут создавать другие типы документов. Django «из коробки» поддерживает как собственную систему шаблонов, так и другую популярную библиотеку Python под названием Jinja2 (она также может быть использована для поддержки других систем, если это необходимо).
Фрагмент кода показывает, как может выглядеть HTML-шаблон, вызванный функцией render() из предыдущего раздела. Этот шаблон был написан с предположением, что во время отрисовки он будет иметь доступ к переменной списка, названной youngest_teams (содержащейся в контекстной переменной внутри функции render() выше). Внутри скелета HTML мы имеем выражение, которое сначала проверяет, существует ли переменная youngest_teams , а затем повторяет её в цикле for . При каждом повторе шаблон отображает значение team_name каждой команды в элементе <li> .
Что ещё можно сделать?
В предыдущих разделах показаны основные особенности, которые вы будете использовать почти в каждом веб-приложении: сопоставление URL-адресов, отображение, модели и шаблоны. Также Django предоставляет несколько других вещей:
- Формы: HTML-формы используются для сбора пользовательских данных для обработки на сервере. Django упрощает создание, проверку и обработку формы.
- Аутентификация пользователя и разрешения: Django включает надёжную систему аутентификации и авторизации пользователей, которая была построена с учётом безопасности.
- Кеширование: Создание динамического контента намного более интенсивно (и медленнее), чем обслуживание статического содержимого. Django обеспечивает гибкое кеширование, чтобы вы могли хранить всю или часть отображаемой страницы, для того, чтобы она не вызывалась повторно, за исключением случаев, когда это необходимо.
- Админ-панель: Административная панель в Django включена по умолчанию при создании приложения с использованием основного каркаса. Это упрощает управление админкой администраторам сайта для создания, редактирования и просмотра любых данных на вашем сайте.
- Сериализация данных (преобразование в последовательную форму): Django упрощает сериализацию и обслуживание ваших данных в таких форматах как XML или JSON. Это может быть полезно при создании веб-сервисов (веб-сайтов, которые исключительно служат для использования данных другими приложениями или сайтами и сами ничего не отображают) или при создании веб-сайта, на котором клиентский код обрабатывает весь рендеринг данных.
Резюме
Поздравляем, вы завершили первый шаг в своём путешествии по Django! Теперь вы должны понимать основные преимущества Django, немного его истории, и примерно как может выглядеть каждая из основных частей приложения Django. Вы должны также изучить несколько вещей о языке программирования Python, включая синтаксис списков, функций и классов.
Вы уже видели код на Django выше, но в отличие от клиентского кода вам нужно настроить среду разработки для её запуска. Это наш следующий шаг.
Для новичка, который осваивает Django, представления на основе классов больше похожи на магию чёрного ящика, по крайней мере, у меня при первом знакомстве сложилось именно такое впечатление. Обильные руководства зачастую показывают, какие атрибуты и методы следует определить в вашем классе, чтобы этот ящик работал на вас, но не дают понимания принципа работы.
Я хочу залезть под капот фреймворка и строчка за строчкой разобрать, как же работают представления на основе классов. Надеюсь, что по прочтении, Class-based views уже не будут казаться такими пугающими и я подстегну вас к дальнейшему самостоятельному изучению исходников. Возможно, вы думали о фреймворке как о некой магии, которую невозможно понять, но на самом деле это обычный код, написанный опытными разработчиками.
Background
Я предполагаю, что у читателя есть базовое представление об ООП в Python и опыт создания проекта на Django. Для более комфортного чтения рекомендую также познакомиться со следующими темами:
В качестве представления на основе класса я возьму абстрактный AboutView , наследника TemplateView , и на этом примере рассмотрю жизнь класса: классы-предки, формирование функции конструктора, вызов из URLConf, примеси и внутреннюю логику работы.
Несмотря на то, что я старался максимально подкрепить мыслительный процесс исходным кодом, я понимаю, что держать в голове нить повествования может быть сложно. Для облегчения задачи я создал блок-схему, на которой можно увидеть все атрибуты и методы класса, откуда они наследуются, и окинуть процесс взаимодействия методов между собой одним взглядом.
0. URL dispatcher
Давайте посмотрим, как бы выглядел urlpatterns на основе привычного Function-based View (FBV) и на Class-based View (CBV):
Исходный код класса TemplateView
Откуда же он взялся? Для ответа на этот вопрос следует рассмотреть всю иерархию наследования AboutView .
1. Class View
Иерархия наследования класса AboutView
Давайте посмотрим на исходный код View:
Исходный код класса View
Для новичка выглядит устрашающе, но мы пойдем по пути, которым следует Django.
Поскольку в URLConf вызывается метод as_view() , примем его за отправную точку. Согласно правилам наследования, если метод не найден в текущем классе, поиск будет продолжен далее по списку MRO и в конце концов он будет обнаружен в классе View :
В сигнатуре метода есть интересные детали, которые заслуживают отдельного внимания: во‑первых, это декоратор @classonlymethod из django.utils.decorators — потомок builtins.classmethod . Из названия можно догадаться, что декоратор гарантирует вызов только из класса. При вызове метода из экземпляра возбуждается исключение AttributeError .
Во‑вторых, привычные **kwargs заменены на **initkwargs — это сделано неспроста. Если бросить взгляд ниже, то можно увидеть, что внутренняя функция view тоже принимает **kwargs параметр. Если бы имя параметра не было изменено, внутренний **kwargs затенил бы внешний, полученный за счёт замыкания. В конечном счёте имя не играет никакой роли, главное здесь оператор распаковки ** — именно он преобразует все именованные параметры в словарь .
Что может получить функция в **initkwargs ? По задумке создателей Django, в as_view можно сразу передавать необходимые атрибуты и тем самым избежать создания класса. Для примера, наш класс AboutView можно было заменить следующим выражением:
Смотрим код дальше. В цикле for перебираются ключи initkwargs , которые проходят две проверки:
Вторая проверка разрешает нам переопределять только известные атрибуты и методы класса:
Далее по коду мы встречаемся с функцией view() , подробности реализации которой нам сейчас не важны, мы вернёмся к ней позже. На данном этапе достаточно понимания того, что в локальном пространстве имён появляется view с типом function .
В следующих двух строках мы добавляем к view два атрибута: .view_class , который содержит ссылку на наш класс AboutView и .view_initkwargs , который содержит словарь initkwargs :
и под конец вызываются два wrapper-метода:
Те, кто знакомы с декораторами уже заметили, что функция as_view как раз им и является, оборачивая и возвращая функцию view . Врапперы — обычное дело для декораторов, они позволяют заменить метаданные оборачиваемой функции. Если вы посмотрите код враппера, то увидите, что атрибуты __module__ , __name__ , __qualname__ , __doc__ , __annotations__ и __dict__ копируются из класса AboutView и метода .dispatch в функцию View .
Наконец, мы заканчиванием нашу работу в as_view и на выходе получаем нашпигованный и подготовленный объект функции view , который и возвращаем в URLConf. То есть сейчас URLConf можно было бы представить следующим образом:
, что делает его очень похожим на обычный FBV.
Теперь предположим, что пользователь запросил у нашего сервера web-страницу, диспетчер URL сопоставил паттерн и вызывает нашу функцию view .
2. View function
Если описать коротко, то именно функция view является главным дирижёром: она создаёт экземпляр класса нашего представления, запускает внутреннюю логику и в итоге возвращает response. Взглянем на код:
Функция принимает три аргумента. Первым передаётся request в виде экземпляра класса WSGIRequest , далее идут аргументы *args и **kwargs , которые содержат именованные аргументы, захваченные из URL адреса . Вот пример того, что может получить функция:
Здесь важно не перепутать **kwargs с **initkwargs , которые доступны функции через замыкание: в **initkwargs мы получаем переопределённые атрибуты для экземпляра класса, а в **kwargs — параметры из URL адреса.
Первое что делает функция view — вызывает класс, передавая ему **initkwargs , тем самым создавая его экземпляр.
Не стоит смущаться названия переменной self , обычно мы привыкли видеть её в параметрах методов. Здесь это просто переменная, что появляется в локальной области видимости, и которой мы присваиваем ссылку на экземпляр класса.
Создавая экземпляр, мы неявно вызываем инициализатор класса __init__ ,
который, проходя по словарю **kwargs (но мы-то помним, что на самом деле он **initkwargs :), создаёт атрибуты экземпляра.
Теперь у нас в переменной self сохранён экземпляр класса AboutView .
После вызывается метод setup , который принимает аргументы, переданные view (те, что захватили из URL), и сохраняет их в экземпляре класса, что делает их доступными для всех других методов экземпляра:
Помимо этого он проверяет, определены ли у экземпляра обработчики методов GET и HEAD: если self.get определён, а self.head нет, то метод создаёт атрибут self.head и перенаправляет на self.get .
После вызова setup() в функции view() выполняется еще одна проверка, чтобы убедиться, что у self есть атрибут запроса:
По итогу функция возвращает нам результат выполнения следующего метода - dispatch() .
3. dispatch()
Работа метода dispatch() отражает его название:
Если же такой глагол нашёлся, диспетчер назначает соответствующий метод переменной handler (для OPTIONS → options, для GET → get , для POST → post ).
Если мы вернёмся и посмотрим полный код класса View , то увидим, что в нём предопределён только один метод options() .
Он вернёт нам ответ на запрос с заголовком Allow с поддерживаемыми методами.
Но что делать, если нам нужно обработать запрос GET?
4. get()
На этом моменте полномочия базового класса View всё :) и в игру вступает его наследник TemplateView , в котором нужный метод определён:
Получая знакомые уже нам атрибуты, класс формирует контекст для шаблона, вызывая метод get_context_data из примеси ContextMixin .
Миксин не занимается rocket science, а всего лишь берёт словарь ключевых аргументов, полученных из URL адреса, добавляет туда ключ 'view' , который ссылается на наш экземпляр класса (таким образом вы сможете обратиться к экземпляру класса прямо из шаблона), и под конец примешивает словарь extra_context , если вы вдруг его переопределяли.
Получив контекст, TemplateView может его отрендерить при помощи примеси TemplateResponseMixin и её метода render_to_response .
5. TemplateResponseMixin
Имена атрибутов информативны сами по себе (но если что вы всегда можете заглянуть в документацию).
Если вдруг вы забыли, то, наследуясь от класса TemplateView, мы переопределили имя шаблона на 'about.html' , именно этот шаблон и будет использоваться для рендера.
Точно так же вы можете переопределять остальные параметры нашего класса, чтобы получить необходимое поведение CBV. Конечно, собирать все атрибуты при множественном наследовании выматывающая работа, но здесь нам на помощь приходит сайт Classy Class-Based Views, в котором вы сразу видите все атрибуты и методы класса и его родителей. Теперь не требуется бежать на StackOverflow, чтобы нагуглить ответ, можно использовать перегрузку аттрибутов с пониманием.
В этом миксине берётся дефолтный TemplateResponse (если вы его не переопределяли), ему передаётся контекст и список шаблонов, полученный с помощью несложного метода get_template_names :
который возвращает имя шаблона внутри списка или возбуждает ошибку, если оно не определено.
И, как финальный результат, экземпляр TemplateResponse возвращается в метод get() , который далее передаёт по цепочке в dispatch() и view() , и на этом работа представления завершается.
Заключение
Конечно, разобрав один из наиболее простых CBV сложно сказать, что уверенно ими владеете, впереди вас ждут более интересные Generic display views, такие как DetailView и ListView с более сложными миксинами и разветвлённым наследованием, но хочется верить, что, прочитав этот материал, вы сможете разобраться в них самостоятельно.
А пока давайте подведём итог полученным знаниям:
CBV базируется на множестве классов и миксинов, но во главе стоит класс View с конструктором экземпляра и методом as_view() .
Вызов метода as_view() в URLConf возвращает нам функцию view() , которую Django будет вызывать при совпадении адреса с паттерном
Вызов функции view() создаёт экземпляр представления и запускает цепочку обработки запроса
В конце цепочки методов-обработчиков нам возвращается экземпляр TemplateResponse , как результат выполнения представления
Полезные ссылки
Classy Class-Based Views — ресурс, позволяющий для каждого CBV увидеть все наследуемые атрибуты и методы
Читайте также: