Виды в виде классов(Class Based Views) и использование миксинов
Теория
В данном посте рассмотрим возможность обернуть методы вида в классы, иначе говоря в Class Based Views и воспользуемся миксинами, чтобы осуществить принцип DRY на уровне кода Python для Django.
В данном посте не будем добавлять в приложение новых фитч, а будем усовершенстововать код, который используется в файле blog/views.py.
Это усовершенствование преследует 2 цели:
Для расширения возможности видов в Django есть специальный класс Views в модуле django.views.generic, а уменьшение повторяемости можно достичь используя миксин в виде отдельного универсального класса для однотипных задач, которые имеют всего лишь разные значения.
Примечание. Mixin — это особый вид наследования в Python (и других объектно-ориентированных языках), и он начинает получать большую популярность в разработке Django / Web Application. Вы можете использовать Mixin, чтобы позволить классам на Python делиться методами между любым другим классом, который наследует от этого Mixin.
В дополнении ко всему рассмотрим, как на уровне вида выдать ошибку 404, вместо стандартного Traceback Django.
Практика
Процесс перехода будем выполнять в несколько этапов, чтобы не пропустить промежуточные итоги усовершенствования кода.
Этап 1. Переход к CBV
На этом этапе заменим функции post_detail() и tag_detail() в blog/view.py на аналогичные по функциональности классы и поправим код в blog/urls.py.
Открываем файл blog/view.py и правим код. Сохраним все предыдущее состояние кода,для наглядности того, что поменяли
Что делает данный код? Мы подключаем модуль django.views.generic и импортируем оттуда класс View, далее создаем 2 класса, которых наследуем от класса View, для переопределения функции get() в них. Этот метод соответствует методу запроса GET, поэтому он должен возвращать рендер шаблона вида с значениям постов и тегов, чтобы показать в браузере пользователя, отправившего этот запрос.
Теперь открываем файл blog/urls.py и правим метод передачи обработки по шаблону запроса маршрутизации с post_detail и tag_detail на PostDetail.as_view() и TagDetail.as_view() соответственно
Перезапускаем и убеждаемся, что все запускается ровно также, как и при старом коде.
Этап 2. Генерация страницы 404
Открываем файл blog/views.py и меняем содержимое на такое
В общем, в данном файле мы все запросы к БД выполняем через функцию get_object-or_404(…), который внутри себя реализует запрос к БД и если ничего не найдено, то выдает страницу 404 вместо Traceback, который не понятен бывалому пользователю сайта

Конструкция Tag.__name__.lower() возвращает название класса(в данном случае название модели) с заглавной буквы, но нам нужны только строчные буквы и поэтому используем функцию lower() и далее передаем его в виде названием параметра словаря контекста. Это нам пригодится, что на следующем этапе определить для этих классов общий миксин.
Этап 3. Создание Миксина
Теперь создадим еще один файл blog/utils.py, в котором определим наш миксин в виде универсального класса для уменьшения кода, который будет унаследован классами с переопределенными свойствами
В данном классе мы определили 2 свойства:
Как мы видим, данный класс-миксин не содержит в себе каких-то индивидуальных параметров, которые бы его ограничивали в использовании. Он универсален для вывода и поста и для тега и это для нас может разыграть отличное условие, чтобы соответствовать принципу DRY в коде Python/Django.
Теперь открываем файл blog/views.py перезаписываем вьюшки с наследованием нашего миксина. Старый код закоментирован, чтобы лучше можно было понять шаги и изменение кода
Перезапускаем сервер и убеждаемся, что все работает также, как и прежде.
Что такое миксины в Python и как их использовать.
В Python нет какого либо специального синтаксиса для поддержки миксинов, по этому классы миксинов, легко можно перепутать с обычными классами, но при этом у них действительно очень большая как семантическая, так и реальная разница с обычными классами.
Так как для реализации поведения миксинов используется простое множественное наследование, то это требует от программиста большой дисциплины, поскольку нарушает одно из основных допущений для миксинов: их ортогональность к дереву наследования, т. е. классы, не зависят друг от друга. В Python миксины живут в обычном дереве наследования, предоставляя дополнительную функциональность и избегают создания иерархий, которые слишком сложны для понимания программистом.
Пример множественного наследования.
Пример использования класса миксина/примеси.
В отличие от приведенного выше примера, класс миксина не предназначен для использования отдельно. Он предоставляет новые методы или переопределяет имеющиеся методы.
Например, в стандартной библиотеке Python, в модуле socketserver есть несколько миксинов. Выдержка из документации:
С помощью этих классов миксинов могут быть созданы поточные версии каждого типа сервера. Например, ThreadingUDPServer создается следующим образом:
Простой пример для понимания поведения классов миксинов.
Иногда молодые программисты не до конца понимают принцип MRO в Python и по этому в некоторых случаях не правильно используют классы миксинов.
Классы-примеси (mixin) в Python
Введение
Примеры
Mixin
Таким образом, чтобы дать классы для Car и Часовой возможность использовать радио, вы можете переопределить Car из предыдущего примера и написать это:
С миксинами важно то, что они позволяют вам добавлять функциональные возможности к разным объектам, которые не разделяют «основной» подкласс с этой функциональностью, но, тем не менее, совместно используют код для него. Без миксинов сделать что-то похожее на приведенный выше пример будет гораздо сложнее и / или может потребоваться некоторое повторение.
Переопределение методов в миксинах
Например, возьмите следующие классы
В этом случае класс Mixin2 является базовым классом, расширенным с помощью Mixin1 и, наконец, с помощью BaseClass. Таким образом, если мы выполним следующий фрагмент кода:
Мы видим возвращаемый результат из базового класса. Это может привести к непредвиденным ошибкам в логике вашего кода и должно учитываться и учитываться
Синтаксис
Параметры
Примечания
Научим основам Python и Data Science на практике
Это не обычный теоритический курс, а онлайн-тренажер, с практикой на примерах рабочих задач, в котором вы можете учиться в любое удобное время 24/7. Вы получите реальный опыт, разрабатывая качественный код и анализируя реальные данные.
Использование миксинов с представлениями на основе классов¶
Контекст и шаблонные ответы¶
Предоставляются два центральных миксина, которые помогают обеспечить согласованный интерфейс для работы с шаблонами в представлениях, основанных на классах.
Построение общих представлений Django на основе классов¶
DetailView : работа с одним объектом Django¶
Чтобы показать детали объекта, нам в основном нужно сделать две вещи: найти объект, а затем сделать TemplateResponse с подходящим шаблоном и этим объектом в качестве контекста.
ListView : работа с большим количеством объектов Django¶
Использование миксинов представления Django на основе классов¶
Теперь мы увидели, как общие представления Django, основанные на классах, используют предоставленные миксины, давайте рассмотрим другие способы их комбинирования. Мы по-прежнему будем комбинировать их либо со встроенными представлениями на основе классов, либо с другими общими представлениями на основе классов, но есть ряд более редких проблем, которые вы можете решить, чем те, которые предусмотрены Django из коробки.
Не все миксины можно использовать вместе, и не все представления, основанные на общих классах, можно использовать со всеми другими миксинами. Здесь мы приводим несколько примеров, которые работают; если вы хотите объединить другие функциональные возможности, то вам придется рассмотреть взаимодействие между атрибутами и методами, которые пересекаются между различными классами, которые вы используете, и как method resolution order будет влиять на то, какие версии методов будут вызываться в каком порядке.
Справочная документация для Django class-based views и class-based view mixins поможет вам понять, какие атрибуты и методы могут вызвать конфликт между различными классами и миксинами.
Использование SingleObjectMixin с View¶
Мы можем легко подключить это к нашим URL-адресам:
Использование SingleObjectMixin с ListView ¶
ListView обеспечивает встроенную пагинацию, но вы можете захотеть просмотреть список объектов, которые все связаны (внешним ключом) с другим объектом. В нашем примере с издательством вы можете захотеть постранично просмотреть все книги определенного издательства.
Теперь мы можем написать новый PublisherDetailView :
В примере paginate_by намеренно сделан маленьким, чтобы вам не пришлось создавать много книг, чтобы увидеть, что пагинация работает! Вот шаблон, который вы хотите использовать:
Избегайте чего-то более сложного¶
Использование FormMixin с DetailView ¶
Вспомните наш предыдущий пример использования View и SingleObjectMixin вместе. Мы регистрировали интерес пользователя к определенному автору; теперь скажем, что мы хотим позволить ему оставить сообщение о том, почему он ему нравится. Опять же, давайте предположим, что мы не собираемся хранить это в реляционной базе данных, а вместо этого в чем-то более эзотерическом, о чем мы не будем здесь беспокоиться.
Наш новый AuthorDetailView выглядит следующим образом:
Лучшее решение¶
Количество тонких взаимодействий между FormMixin и DetailView уже проверяет нашу способность управлять вещами. Маловероятно, что вы захотите написать такой класс самостоятельно.
В этом случае вы могли бы написать метод post() самостоятельно, сохранив DetailView как единственную общую функциональность, хотя написание кода обработки Form подразумевает много дублирования.
В качестве альтернативы, это было бы менее трудоемко, чем вышеописанный подход, иметь отдельное представление для обработки формы, которое могло бы использовать FormView в отличие от DetailView без проблем.
Альтернативное лучшее решение¶
Вы можете передавать аргументы ключевых слов в as_view() таким же образом, как и в URLconf, например, если вы хотите, чтобы поведение AuthorInterestFormView также появлялось в другом URL, но с использованием другого шаблона:
Больше, чем просто HTML¶
Представления, основанные на классах, эффективны, когда вы хотите делать одно и то же много раз. Предположим, вы пишете API, и каждое представление должно возвращать JSON вместо HTML.
Мы можем создать класс mixin, который будет использоваться во всех наших представлениях, обрабатывая преобразование в JSON один раз.
Например, миксин JSON может выглядеть следующим образом:
Ознакомьтесь с документацией Сериализация объектов Django для получения дополнительной информации о том, как правильно преобразовывать модели Django и наборы запросов в JSON.
Редактирование миксинов¶
Для построения представлений редактирования в Django используются следующие миксины:
FormMixin ¶
Класс-миксин, предоставляющий средства для создания и отображения форм.
Миксины
Методы и атрибуты
Словарь, содержащий исходные данные для формы.
Класс формы для инстанцирования.
URL-адрес для перенаправления после успешной обработки формы.
prefix для сгенерированной формы.
get_form ( form_class = None )¶
Создайте аргументы ключевых слов, необходимые для инстанцирования формы.
Выдает ответ, предоставляя недействительную форму в качестве контекста.
Вызывает get_form() и добавляет результат в контекстные данные с именем „form“.
ModelFormMixin ¶
Миксины
Методы и атрибуты
URL-адрес для перенаправления после успешной обработки формы.
success_url может содержать форматирование строки словаря, которое будет интерполировано на атрибуты поля объекта. Например, вы можете использовать success_url=»/polls/
Выдает ответ, предоставляя недействительную форму в качестве контекста.
ProcessFormView ¶
Миксин, обеспечивающий базовый рабочий процесс HTTP GET и POST.
Расширяется
Методы и атрибуты
Создает форму, проверяет ее на валидность и обрабатывает соответствующим образом.
DeletionMixin ¶
Методы и атрибуты
url для перенаправления после успешного удаления номинированного объекта.
success_url может содержать форматирование строки словаря, которое будет интерполировано на атрибуты поля объекта. Например, вы можете использовать success_url=»/parent/




