1.1 Серверная часть
Сервер написан на Python-фреймворке Django, который широко применяется для веб приложения. Благодаря большому количеству модулей в нем, его можно использовать для проектов любой сложности и задачи.
На серверной части можно выделить три главных компонента, которые соответствуют трем компонентам шаблона проектирования MVC (шаблон полностью описан в следующих разделах пояснительной записки): модель, представление, контроллер. В модели сосредоточена основанная бизнес-логика приложения, контроллер – связующее звено между моделью и представлением, который также управляет потоком данных, а представление – итоговая html-страница, которую видит пользователь.
Контроллер — это код, запускаемый в ответ на поступление клиентского запроса, который содержит интернет-адрес определенного формата. Именно в контроллерах выполняются все действия по подготовке данных для вывода, равно как и обработка данных, поступивших от посетителя.
Контроллер Django может представлять собой как функцию (контроллер-функция), как и класс (контроллер-класс), которые представлены на рисунке 1.1. Первые более универсальны, но зачастую трудоемки в программировании, вторые позволяют выполнить типовые задачи, наподобие вывода списка каких-либо позиций, минимумом кода.
Основная часть функциональности различных контроллеров-классов реализована в примесях (классах, предназначенных лишь для расширения функциональности других классов), от которых наследуют контроллеры-классы.
Рисунок 1.1— Контроллер-функция и контроллер-класс
ListView самостоятельно извлекает из модели набор записей, записывает его в атрибут object_list (чтобы успешно работали наследуемые им примеси) и выводит на экран страницу со списком записей. Контроллер RuleListView унаследован от LoginRequiredMixin и ListView. Первый контроллер-класс не позволяет неавторизированными пользователям посетить данную страницу, перенаправляя их на форму авторизации. Плюс ко всему сказанному, данный класс контролирует обратное перенаправление на ту странуцу, куда пользователь хотел попасть изначально. Второй класс позволяет выводить шаблон со всеми записями модели Regulation, сохраненных в контексте шаблона.
Пользователи могут быть неавторизированными и авторизированными. Неавторизированными будут новые пользователи или те, кто ранее вышли из системы, а авторизированными являются пользователи, вошедшие в приложение раннее. Даже при перезапуске сервера, пользователи, которые были в системе, в ней и останутся, так как вся информация о сессиях сохраняется не в приложения, а в отдельной таблице БД.
Авторизация пользователя проходи в контроллере-функции user_login (рисунок 1.2). Прежде всего проверяется, какой запрос был отправлен. В случаи POST запроса, проверяется правильность заполнения формы, после чего проверяется, есть ли данный пользователь и его пароль. При успешной авторизации пользователь перенаправляется на главную страницу.
Рисунок 1.2— Авторизация пользователя
Для формирования списка доступных пользователю используется контроллер QuizListView (рисунок 1.3). Здесь переопределен метод get_queryset, который отвечает за формирование контекста для шаблона. Данные естественно берутся из базы данных. Сначала мы получаем список тестов, которые пользователь еще ни разу не проходил. Далее находим список тестов, которые пользователь отвечал, но может повторить. То есть при прохождении теста, он будет доступен для прохождения только через 2 часа. Все результаты тестов сохраняются в модель TakenQuiz, которой соответствует таблица в базе данных.
Рисунок 1.3— Контроллер QuizListView
Для пользователя также реализована страница для редактирования его профиля. За формирование и изменение профиля отвечает контроллер edit_profile. Он представлен на рисунке 1.4. Сначала формируется форма, в которую заносится уже известная информация об пользователе: его аватар(каждому пользователю существует картинка по умолчанию), дата рождения, если заполнена, его опыт, который получает он за прохождение тестов. Далее в этой форме, при желании, вносится изменения, после чего форма проходит валидацию. При успешном изменении профиля система выводит сообщение об этом. Данные профиля сохраняются в соответствующей модели Profile. Данная модель связана с моделью пользователя, которая предоставлена Django по умолчанию, один к одному.
Рисунок 1.4— Контроллер edit_profile
1.2 Клиентская часть
Будучи веб фреймверком, Django позволяет динамически генерировать HTML. Самый распространенный подход - использование шаблонов. Шаблоны содержат статический HTML и динамические данные, рендеринг которых описан специальным синтаксисом.
Проект Django может использовать один или несколько механизмов создания шаблонов (или ни одного, если вы не используете шаблоны). Django предоставляет бэкенд для собственной системы шаблонов, которая называется - язык шаблонов Django (Django template language, DTL), и популярного альтернативного шаблонизатора Jinja2. Сторонние приложения могут предоставлять бэкенд и для других систем шаблонов.
Шаблон — это образец для формирования веб-страницы, которая будет отправлена посетителю в ответ на его запрос. Также шаблон может применяться для формирования текстовых документов — например сообщений электронной почты.
Шаблонизатор - подсистема фреймворка, непосредственно формирующая окончательные веб-страницы (и текстовые документы), объединяя шаблоны и предоставленные контроллерами контексты шаблонов, содержащие все необходимые данные.
Преимуществом является то, что есть возможность создать базовый шаблон, а после чего его наследовать в другие, тем самым сокращая объем кода. Все шаблоны хранятся в папке templetes приложения.
Теги шаблонизатора управляют генерированием содержимого результирующего документа. Они записываются в формате:{ %< собственно запись тега со всеми необходимыми параметрами> % }
Как и НТМL-теги, теги шаблонизатора бывают одинарными и парными. Одинарный тег просто помещается в нужное место кода шаблона. Как правило, он вставляет в это место какое-либо значение, вычисляемое самим фреймворком. Пример одинарного тега, вставляющего в код шаблона электронный жетон, который используется подсистемой безопасности фреймворка:{% csrf token %}
Парный тег «охватывает» целый фрагмент кода шаблона. Он применяется для выполнения над этим фрагментом каких-либо действий. Например, парный тег for .. in повторяет содержащийся в нем фрагмент столько раз, сколько элементов находится в указанной в этом теге последовательности. Пример реализации на рисунке 1.5.
Как видим, парный тег фактически состоит из двух тегов: открывающего и закрывающего (в приведенном только что примере это теги for .. in и endfor). Закрывающий тег имеет то же имя, что и открывающий, но с добавленным впереди префиксом end. Фрагмент кода, находящийся внуrри парного тега, носит название содержимого.
Рисунок 1.5— Пример парного тега for
Особенностью является также возможность использовать фильтры шаблонизатора. Они выполняют определенные преобразования значения перед его выводом. Фильтр записывается непосредственно в директиве, после имени переменной, из которой извлекается текущее значение для обработки, и отделяется от нее символом вертикальной черты (рисунок 1.6).
В данном примере используется фильтр first, который дает возможность получить первый элемент из переменной word. Также используется функция length, которая возвращает значение длины списка.
Рисунок 1.6— Пример фильтра шаблонизатора
Аналогично наследованию классов, практикуемому в Python, Django предлагает нам механизм наследования шаблонов. В Python базовый класс определяет функциональность, которая должна быть общей для всех наследующих его производных классов. Точно так же и вDjango: базовый шаблон определяет все элементы, которые должнь1 быть общими для всех наследующих его производных шаблонов. Помимо этого, базовый шаблон определяет набор блоков. Блок представляет собой место в коде базового шаблона, куда производный шаблон поместит свое уникальное содержимое. Таких блоков может быть сколько угодно.
Дата | Выполнено, % |
---|---|
2020-05-19 19:37:36 | 10 |
2020-05-14 09:03:38 | 100 |