Использование adobjects совместно с adapi образует Headless CMS — систему, которая позволяет осуществлять взаимодействие через универсальный формат API независимо от интерфейса.
Библиотека для быстрой разработки серверной части Веб-Бизнес-приложений на Python построенная на принципах минимизации написания кода (low-code) и предметно-ориентированного проектирования (Domain-Driven Design).
Для разработки используется фреймворк Django - свободный фреймворк для веб-приложений на языке Python. Django содержит огромное количество функциональности для решения большинства задач веб-разработки и отличную документацию.
Для разработки серверной части Веб-Бизнес-приложений данную библиотеку необходимо использовать совместно с adapi, что позволяет реализовать RESTful API без написания кода на основе моделей.
Для ускорения разработки библиотека содержит стандартные абстракции моделей предметной области, для проектирования приложения, необходимо описать объекты предметной области через абстракции библиотеки, как показывает опыт других решений построенных на схожих идеях, любое бизнес-приложение можно описать через набор стандартных моделей. На сегодня реализованы следующие модели:
Так же предполагается разработать:
Для модели Справочника и Документа предусмотрены механизмы блокировок. С их функциональностью можно ознакомиться здесь.
Важным преимуществом упрощающим и упорядочивающим разработку является выделение концепции сервисного слоя, куда выносится вся бизнес-логика объектов, это позволяет “очистить” и отделить слой описания объектов (моделей). Основная часть бизнес-логики представляет собой обработчики стандартных событий и методов объектов предметной области (подробнее модель событий и методы в описании объектов), так же есть возможность добавлять специфичные методы для объектов.
Ознакомиться с возможностями сервисного слоя можно здесь
Для того чтобы использовать adobjects
достаточно произвести установку пакета, и необходимых настроек,
после чего можно создавать модели наследуя их от базовых объектов библиотеки:
``../models.py``
from adobjects.models import ИмяОбъекта
class ИмяМодели(ИмяОбъекта):
ПользовательскиеПоля
... Все. Типовой объект создан готов!
————v
Установка с использованием pip
(рекомендуется)…
$ pip install git+https://<PERSONAL ACCESS TOKEN>@github.com/Digitatl/ADOBJECTS.git
или из источника…
$ git clone https://github.com/Digitatl/ADOBJECTS.git
$ cd adobjects
$ pip install -e .
Рекомендуемые настройки settings.INSTALLED_APPS
INSTALLED_APPS = [
...
'adobjects',
...
]
Сервисный слой состоит из бизнес-логики, которая отделена от уровня данных и других.
Следует договориться о создании отдельных модулей services
на уровне каждого Django-приложения.
project_name
├── app_name
│ ├── services
│ │ ├──init.py
│ │ ├──model_name.py
| | ├...
| | ...
│ ├── urls
│ ├── models
...
Модуль services
является слоем для бизнес-логики. В нем размещаются файлы с названиями совпадающими с наименованиями моделей.
В этих файлах описывается бизнес-логика присущая конкретным моделям.
Примеры использования сервисного слоя приведены здесь.
Для создания или переопределения методов объекта модели необходимо в файле app_name.services.model_name.py создать класс с именем <ИмяМодели>, в который необходимо добавить нужный метод/методы.ИмяМодели>
После этого к описанным методам можно обратиться.
Для создания или переопределения методов менеджера модели необходимо в файле app_name.services.model_name.py создать класс с именем Manager<ИмяМодели>, в который необходимо добавить нужный метод/методы.ИмяМодели>
После этого к описанным методам можно обратиться.
При использовании библиотеки adapi возможно создание action из методов модели и методов менеджера.
Для этого необходимо ДОПОЛНИТЬ, параметр модели list_manager_actions
наименованиями методов менеджера и параметр list_model_actions
наименованиями методов модели.
После этого можно произвести GET запрос как если бы это был action объекта View
В объектах Справочника и Документа можно установить блокировку - отметку о захвате объекта транзакцией с целью предотвращения коллизий и поддержания целостности данных. Объекты обладают методами:
Время последней блокировки
и Заблокировавший пользователь
будут сохранены соответствующие данные.Представленные прикладные объекты содержат в себе следующие типы методов:
Подробнее о каждом типе прикладных объектов будет сказано в описании соответствующих разделов.
Перечисления являются средством для работы с элементами данных, список возможных значений которых жестоко задан. Ссылки на элементы перечисления могут быть использованы в реквизитах объектов.
Например, можно задать перечисление “Тип учреждения”, определяющее допустимые типы учреждений, со значениями “Бюджетное” и “Автономное”.
Справочники предназначены для работы с постоянной и условно постоянной информацией, имеющей списочный характер.
Например, справочниками могут являться списки организаций, услуг, видов расчета и т.д.
На этапе создания модели можно описать, какими свойствами обладает каждый конкретный справочник:
Наименование метода | Описание |
---|---|
save | Записывает элемент справочника в базу данных. Вызывает обработчики события Записать. |
delete | Устанавливает/снимет пометку на удаление. Объект при этом не удаляется из базы данных. Вызывает обработчик события Удалить. |
get_tabular_sections | Возвращает записи в табличных частей документа. |
check_filling | Выполняет проверку заполнения. Проверяет заполнение реквизитов. Вызывает событие ПроверитьЗаполнение и его обработчик fill_check_processing. |
fill | Заполняет элемент данными из другого объекта. Инициирует событие Заполнить и вызов обработчика filling. В ней может размещаться алгоритм, заполняющий данные элемента из переданного значения. |
is_locked | Определяет, заблокирован ли элемент. |
lock | Выполняет установку блокировки объекта от изменения другими пользователями. |
unlock | Выполняет разблокировку элемента, если он был заблокирован. |
Наименование метода | Описание |
---|---|
copy | Создает новый элемент копированием существующего. |
create_item | Создает новый элемент. Использование метода не приводит к записи созданного объекта в базу данных. |
check_filling, fill, is_locked, lock, unlock, create_item, copy
Обработчики событий могут быть переопределены в сервисном слое для добавления дополнительной логики.
Наименование обработчика | Описание |
---|---|
before_write | Возникает перед выполнением записи элемента. Процедура-обработчик вызывается после начала транзакции записи, но до начала записи элемента. |
on_write | Возникает при записи объекта. Процедура-обработчик вызывается после записи объекта в базу данных, но до окончания транзакции записи. |
before_delete | Возникает перед непосредственным удалением объекта из базы данных. |
on_copy | Возникает при создании элемента справочника копированием. |
filling | Возникает при вводе элемента на основании, а также при выполнении метода Заполнить. В процедуре-обработчике этого события должен быть описан сам алгоритм заполнения реквизитов элемента на основании переданного значения. |
fill_check_processing | Позволяет реализовать проверку заполнения в обработчике события. При этом в обработчике можно полностью отказаться от системной обработки (очистив список проверяемых реквизитов), отказаться от проверки системой части реквизитов (выполнив проверку отдельных реквизитов особенным образом и исключив эти реквизиты из списка), а также добавить для проверки другие реквизиты, проверка которых не была указана. |
before_create | Возникает при создании нового элемента. |
on_copy | Возникает при создании справочника копированием. |
on_set_new_code | Возникает в момент, когда выполняется установка нового кода элемента справочника. |
Документы - электронные аналоги обычных бумажных документов. Они позволяют хранить информацию о совершенных операциях или о произошедших событиях.
Например, в приложении, предназначенном для расчета финансирования, могут быть такие документы, как расчет, регистрация значений показателя и т.д.
На этапе создания модели можно описать, какими свойствами обладает каждый конкретный документ.
| Наименование метода ⠀⠀ | Описание | |—————————|:———————————————————————————————————————————————————————————————–| | save | Записывает документ в базу данных. Вызывает обработчики события Записать. | | delete | Устанавливает/снимет пометку на удаление. При этом объект при этом не удаляется из базы данных и происходит снятие документа с регистрации. Вызывает обработчик события Удалить. | | register_records | Возвращает коллекции наборов записей движений документа. | | post | Регистрирует документ. | | unpost | Снимает документ с регистрации | | check_filling | Выполняет проверку заполнения. Проверяет заполнение реквизитов. Вызывает событие ПроверитьЗаполнение и его обработчик fill_check_processing. | | fill | Заполняет элемент данными из другого объекта. Инициирует событие Заполнить и вызов обработчика filling. В ней может размещаться алгоритм, заполняющий данные элемента из переданного значения. | | is_locked | Определяет, заблокирован ли элемент. | | lock | Выполняет установку блокировки объекта от изменения другими пользователями. | | unlock | Выполняет разблокировку элемента, если он был заблокирован. |
| Наименование метода | Описание | |————————|:—————————————————————————————————| | copy | Создает новый элемент копированием существующего. | | create_item | Создает новый элемент. Использование метода не приводит к записи созданного объекта в базу данных. |
post, unpost, check_filling, fill, is_locked, lock, unlock, create_item, copy
Обработчики событий могут быть переопределены в сервисном слое для добавления дополнительной логики.
Наименование обработчика | Описание |
---|---|
before_write | Возникает перед выполнением записи элемента. Процедура-обработчик вызывается после начала транзакции записи, но до начала записи элемента. |
on_write | Возникает при записи объекта. Процедура-обработчик вызывается после записи объекта в базу данных, но до окончания транзакции записи. |
before_delete | Возникает перед непосредственным удалением объекта из базы данных. |
on_copy | Возникает при создании элемента справочника копированием. |
filling | Возникает при вводе элемента на основании, а также при выполнении метода Заполнить. В процедуре-обработчике этого события должен быть описан сам алгоритм заполнения реквизитов элемента на основании переданного значения. |
fill_check_processing | Позволяет реализовать проверку заполнения в обработчикесобытия. При этом в обработчике можно полностью отказаться от системной обработки (очистив список проверяемых реквизитов), отказаться от проверки системой части реквизитов (выполнив проверку отдельных реквизитов особенным образом и исключив эти реквизиты из списка), а также добавить для проверки другие реквизиты, проверка которых не была указана. |
before_create | Возникает при создании нового элемента. |
on_set_new_number | Возникает в момент, когда выполняется установка нового номера документа. |
posting | Возникает при проведении документа. Основное назначение процедуры-обработчика данного события - генерация движений по документу. Выполняется в транзакции записи. |
unposting | Возникает при снятии пометки проведения у документа. Выполняется в транзакции записи. |
on_copy | Возникает при создании документа копированием. |
Составная часть многих объектов. Предназначена для хранения информации, структура которой одинакова для всех элементов прикладного объекта, при этом количество такой информации может быть различным.
| Наименование метода | Описание | |————————-|:————————————————————————–| | save | Записывает элемент из базы данных. Вызывает обработчики события Записать. | | delete | Удаляет элемент из базы данных. Вызывает обработчик события Удалить. |
Обработчики событий могут быть переопределены в сервисном слое для добавления дополнительной логики.
Наименование⠀⠀⠀ обработчика | Описание |
---|---|
before_write | Возникает перед выполнением записи элемента. Процедура-обработчик вызывается после начала транзакции записи, но до начала записи элемента. |
on_write | Возникает при записи объекта. Процедура-обработчик вызывается после записи объекта в базу данных, но до окончания транзакции записи. |
before_delete | Возникает перед непосредственным удалением объекта из базы данных. ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ |
Оборотный регистр накопления позволяет хранить данные в разрезе нескольких измерений и времени.
Например, в оборотном регистре можно хранить суммы закупок оборудования в разрезе организаций.
На этапе создания модели можно описать, какими свойствами обладает каждый конкретный регистр сведений:
| Наименование метода ⠀⠀ | Описание | |—————————|:————————————————————————————————————————————————————————————————| | save | Записывает элемент регистра в базу данных. Вызывает обработчики события Записать. | | delete | Удаляет элемент из базы данных. Вызывает обработчик события Удалить. | | check_filling | Выполняет проверку заполнения. Проверяет заполнение реквизитов. Вызывает событие ПроверитьЗаполнение и его обработчик fill_check_processing. | | fill | Заполняет элемент данными из другого объекта. Инициирует событие Заполнить и вызов обработчика filling. В ней может размещаться алгоритм, заполняющий данные элемента из переданного значения. |
| Наименование метода | Описание | |———————–|:——————————————————————————————————-| | create_item | Создает новый элемент. Использование метода не приводит к записи созданного объекта в базу данных. | | select_by_recorder | Формирует выборку записей регистра сведений по регистратору. |
check_filling, fill
Обработчики событий могут быть переопределены в сервисном слое для добавления дополнительной логики.
Наименование обработчика | Описание |
---|---|
before_write | Возникает перед выполнением записи элемента. Процедура-обработчик вызывается после начала транзакции записи, но до начала записи элемента. |
on_write | Возникает при записи объекта. Процедура-обработчик вызывается после записи объекта в базу данных, но до окончания транзакции записи. |
before_delete | Возникает перед непосредственным удалением объекта из базы данных. |
filling | Возникает при вводе элемента на основании, а также при выполнении метода Заполнить. В процедуре-обработчике этого события должен быть описан сам алгоритм заполнения реквизитов элемента на основании переданного значения. |
fill_check_processing | Позволяет реализовать проверку заполнения в обработчике события. При этом в обработчике можно полностью отказаться от системной обработки (очистив список проверяемых реквизитов), отказаться от проверки системой части реквизитов (выполнив проверку отдельных реквизитов особенным образом и исключив эти реквизиты из списка), а также добавить для проверки другие реквизиты, проверка которых не была указана. |
before_create | Возникает при создании нового элемента. |
Регистр сведений позволяет хранить произвольные данные в разрезе нескольких измерений и, при необходимости, времени.
Например, в регистре сведений можно хранить численность сотрудников в разрезе организаций.
На этапе создания модели можно описать, какими свойствами обладает каждый конкретный регистр сведений:
| Наименование метода ⠀⠀ | Описание | |—————————|:————————————————————————————————————————————————————————————————| | save | Записывает элемент регистра в базу данных. Вызывает обработчики события Записать. | | delete | Удаляет элемент из базы данных. Вызывает обработчик события Удалить. | | slice_last | Возвращает наиболее поздние записи регистра, соответствующие установленной в параметрах значению даты. | | check_filling | Выполняет проверку заполнения. Проверяет заполнение реквизитов. Вызывает событие ПроверитьЗаполнение и его обработчик fill_check_processing. | | fill | Заполняет элемент данными из другого объекта. Инициирует событие Заполнить и вызов обработчика filling. В ней может размещаться алгоритм, заполняющий данные элемента из переданного значения. |
| Наименование метода | Описание | |———————–|:——————————————————————————————————-| | slice_last | Возвращает наиболее поздние записи регистра, соответствующие установленной в параметрах значению даты. | | create_item | Создает новый элемент. Использование метода не приводит к записи созданного объекта в базу данных. | | select_by_recorder | Формирует выборку записей регистра сведений по регистратору. |
check_filling, fill, slice_last
Обработчики событий могут быть переопределены в сервисном слое для добавления дополнительной логики.
Наименование обработчика | Описание |
---|---|
before_write | Возникает перед выполнением записи элемента. Процедура-обработчик вызывается после начала транзакции записи, но до начала записи элемента. |
on_write | Возникает при записи объекта. Процедура-обработчик вызывается после записи объекта в базу данных, но до окончания транзакции записи. |
before_delete | Возникает перед непосредственным удалением объекта из базы данных. |
filling | Возникает при вводе элемента на основании, а также при выполнении метода Заполнить. В процедуре-обработчике этого события должен быть описан сам алгоритм заполнения реквизитов элемента на основании переданного значения. |
fill_check_processing | Позволяет реализовать проверку заполнения в обработчике события. При этом в обработчике можно полностью отказаться от системной обработки (очистив список проверяемых реквизитов), отказаться от проверки системой части реквизитов (выполнив проверку отдельных реквизитов особенным образом и исключив эти реквизиты из списка), а также добавить для проверки другие реквизиты, проверка которых не была указана. |
before_create | Возникает при создании нового элемента. |
Пусть существует модель документа в приложении test_app
, описанная следующим образом
class DocTest(ModelDocument):
comment = models.TextField(verbose_name='Комментарий', null=True, blank=True)
class Meta:
"""Описание метакласса DocTest."""
verbose_name = 'Тестовый документ'
number_periodicity = 'YEAR'
Добавим к данной модели метод, который возвращает id документа и значение поля comment
(комментарий).
Для этого создадим класс в файле test_app.services.doc_test.py
class ADDocTest:
def print_comment(self):
return f"id документа - {self.pk}, Комментарий - {self.comment}"
Готово! Теперь модель DocTest
содержит метод print_comment
Пример вызова метода:
document = DocTest.objects.get(pk=1)
print(document.print_comment())
Результат
"id документа - 1, Комментарий - Тестовый комментарий"
Прикрепим метод созданный в Примере 1 к View в качестве action.
Для этого дополним параметр list_model_actions
class DocTest(ModelDocument):
comment = models.TextField(verbose_name='Комментарий', null=True, blank=True)
list_model_actions = getattr(ModelDocument, 'list_model_actions') + ['print_comment']
class Meta:
"""Описание метакласса DocTest."""
verbose_name = 'Тестовый документ'
number_periodicity = 'YEAR' Готово! Можно делать запрос.
GET /doc-test/1/print_comment
Ответ:
"id документа - 1, Комментарий - Тестовый комментарий"
Добавим к менеджеру тестовой модели метод, который возвращает id всх существующих документов. Для этого создадим класс в файле test_app.services.doc_test.py
class ADManagerDocTest:
def get_id_all_documents(self):
queryset = self.all()
list_id = [row.pk for row in queryset]
return list_id
Готово! Теперь менеджер модели DocTest
содержит метод get_id_all_documents
Пример вызова метода:
print(DocTest.objects.get_id_all_documents())
Результат
[1, 2, 3, 4, 5 ...]