Pull to refresh

Comments 12

В чем смысл пилить в джанге репозитории, когда джанго орм уже и так представляет из себя достаточную абстракцию над несколькими субд? Там же много всего завязано на модели джанго орм.

Теоретически такое может быть выгодно когда, внезапно, вам нужно сменить фреймворк на полпути, а всю логику переписывать не хочется.

Или не сменить, а добавить какой-то сторонний функционал. Например, вы делаете веб для юзеров на джанге, а соседняя команда делает API с FastAPI, но логика будет общая - выносим её в отдельную библиотеку, а доступ к хранению объектов делаем уже на стороне приложения - через Django или sqlalchemy..

Я сам так не делал и мне самому такой подход не очень нравится, но я просто пофантазировал где это можно применить.

Я понимаю, что эти фантазии имеют место быть, но на мой взгляд эти оба кейса это дикость, т.к. в джанге многое завязано на модели как они есть. Взять те же class based views из самой джанги или из DRF, модуль аутентификации с user model, а сколько разных батареек ждёт джанговскую модель... Я не вижу особой разницы между этим вариантом и переписыванием с нуля хоть на другом фреймворке, хоть на другом вообще стеке.
Второй вариант тоже выглядит весьма сомнительным, так как мы вместо уменьшения связности идём наоборот в сторону её увеличения. У нас оба фреймворка предназначены практически для одной и той же задачи, с разницей лишь в нюансах и мы из каких-то мутных побуждений берём их оба и строим франкенштейна (ну тут просто удачи, что сказать). Помимо того, что у нас в коде переплетены 2 фреймворка, так у нас ещё значительно вырастает количество зависимостей, за которыми надо следить, у нас увеличивается сложность поддержки проекта, увеличиваем требования к экспертизе разработчиков в команде. В таком случае проще выделять из Django что-то в отдельные независимые сервисы на fastapi, если есть в этом необходимость и уменьшать связность.

Да, в общем-то да, меньше кода не будет, а править, скорее всего, тоже придется в трёх местах (Django, FastAPI и еще эта абстракция). Наверное, есть какие-то варианты когда это нужно, но удачный пример придумать сходу сложно.

Django используется, как решение, в котором многое работает из коробки. Сначала, пишется монолит на Django с применением сервисного слоя + слоя репозитория. Потом, монолит распиливается.

Ещë один вариант использования: когда данные хранятся не только в одной БД. Например, на Django пилится сервис, который существует в среде микросервисов, и часть данных он берëт от них, сводя в единый датакласс или TypedDict. По аналогии, ситуация может вынудить нас использовать Redis для обширного кеширования, либо, использовать не реляционную БД для сохранения большого объëма данных, не участвующих в фильтрации. Поэтому, часть данных мы выбираем из БД, часть - из других источников. И Репозиторий является единственной точкой сведения этих данных.

В Django в роли репозитория выступает Model Manager. Именно в нëм можно представить модели в виде коллекций. Однако, у джанговских абстракций есть неприятная особенность: их не так просто переиспользовать.

Например, Manager уже обладает некоторыми методами, которые являются, по сути, алиасами на методы QuerySet. Create, filter, get. То есть, если я захочу переписать метод filter, это может отразиться на других методах менеджера, а моë представление не получит удобную апишку для запроса коллекций. Плюс, к менеджеру я могу обратиться только из модели, к которой он присоединëн. Это создаëт дополнительные проблемы читаемости тогда, когда я хочу, например, получить не QuerySet или инстанс модели, а, скажем, список со словарями. Или список с айдишниками, используя .values или values_list.

Здесь есть проблематика понимания того, что модель и QuerySet являются абстракциями, которые однозначно связаны с БД и формальным языком запросов к БД. А Репозиторий - это абстракция, которая переводит (транслирует) запрос от сервисного слоя - в query language. И джанговский менеджер очень плохо подходит на эту роль из-за особенностей реализации.

Project модель не только хранит данные о проектах, но также имеет методы для управления статусом проекта is_active, close_project, extend_project. Это оч. распространенная проблема.

А дальше альтернатива вообще не про Project. Логично было бы показать именно на примере Project как разделить его логику и почему это стало удобнее.

Вместо этого показан какой-то Task в вакууме)

Действительно очень отличная статья. Давно искал подобное, чтобы разобраться в антипаттернах. Автору огромный респект. Если бы было сказано пару слов о правильном распределении бизнес-логики в слоях джанги - цены бы этой статье не было

где бы найти статью, написанную не для рекламы блога...

Magic numbers И hardcoded - это безотносительно к джанго bad practice.

К "Fat Models" и "Альтернативы".

Почему использование классов ("данные" + "методы") вдруг стало проблемой?
И каким образом создание лишних файлов (типа "репозиторий" и т.п.) делает "код более гибким и удобным для тестирования."?
В будущем (при поддержке, тестировании и масштабировании) для любого простого действия нужно будет открыть не один файл (причем понятно какой),
а два (а при таком подходе их будет неопределенное число, да еще нужно последовательно найти эти файлы... они ведь не являются типовыми для Django).
Может нужно просто правильно научится работать с моделью классов?

Все эти "репозитории" и иже с ними и есть самые настоящие "костыли".
Если для решения конкретной задачи Django не подходит или подходит процентов на 15-20, то нужно использовать другие решения.
А сила использования любого фреймворка в том и заключается, чтобы использовать
его подходы и типовые решения по максимуму для эффективности разработки
(и кстати эффективности системы в целом, т.к. сам Django оптимизируется именно под свои решения).

Это конечно не исключает необходимости думать.
А еще заниматься проектированием (и классов, и методов, и слоев обработки и представления данных) перед собственно кодированием.
Наследование кстати тоже пока никто не отменял.
Это к вопросу о "толщине" модели и "монолитности блоков кода"

И к вопросу "абстрагироваться от специфики хранения данных".
От чего Вы предлагаете "абстрагироваться"? От моделей Django?
Лучше тогда сразу выбрать другой фреймворк.

В чем смысл этого "сервисного слоя" кроме запутывания кода и лишних запросов к БД? Тем более в примере он не проверяет текущий статус задачи, тут лучше бы FSM подошел, но они эти методы тоже хранят в модели. Вообще логику можно было бы положить в сериализатор или форму, как принято в самой джанге. И как создание лишних абстакция помогает тестированию?

В "репозиториях" тоже не вижу смысла, тем более как сказали выше есть manager`ы.

Sign up to leave a comment.