Отчеты предоставляют возможность получения данных с произвольными итогами и группировками для одной или нескольких таблиц в удобном для просмотра и анализа виде.
Библиотека позволяет создавать API для формирования универсальных отчетов по любым моделям.
Создание отчета происходит путем создания виртуальной таблицы запросом SQLAlchemy. Структура данных описывается моделью Django.
Универсальный механизм отчетов предоставляет возможности:
Для того чтобы использовать django-report-api
достаточно произвести установку пакета, и необходимых настроек,
после чего необходимо подключить создать и подключить модели отчетов для которых хотим создать универсальный API:
При этом, у модели должен присутствовать метод get_report_query
содержащий логику получения запроса с данными.
../models.py
from django_report_api.models import BaseReportModel
class ReportModelName(BaseReportModel):
...
class Meta:
abstract = True
def get_report_query(self):
return Запрос SQLAlchemy
...
../urls.py
from ... import ReportModelName, ...
from django_report_api.report_router import router
router.register(ReportModelName)
...
Универсальный механизм отчетов со всеми возможностями описанными [выше](#main) готов! ---
(Рекомендуется совместное использование с библиотекой ADAPI)
Установка с использованием pip
(рекомендуется)…
$ pip install git+https://<PERSONAL ACCESS TOKEN>@github.com/Digitatl/django-report-api.git
Или из источника...
$ git clone https://github.com/Digitatl/django-report-api.git
$ cd adapi
$ pip install -e . ---
Необходимые настройки settings.INSTALLED_APPS
.
INSTALLED_APPS = [
...
'rest_framework',
'aldjemy',
'django_report_api',
...
]
Выбрать какие поля будут содержаться в ответе можно с помощью параметра параметр fields
Например, Вам нужен список пользователей, но вас интересуют только поля “id” и “username”:
GET /users/?fields=id,username
[
{
"id": 1,
"username": "user1"
},
{
"id": 2,
"username": "user2"
}
] ### <a name="group_by_report"></a> Группировка результатов с расчетом агрегатных функций Группировка позволяет "свернуть" таблицу по указанным в параметре group_by полям.
Для расчета агрегатных функций (суммы, среднего, подсчета количества, поиск максимума/минимума) по полям с группировкой
необходимо указать в параметре fields
тип агрегатной функции.
Например, Вам нужен список наименований товаров, с суммой по полю number_of_sales
для каждого товара:
GET /product/?fields=name,number_of_sales__sum&group_by=name
[
{
"name": "Утюг",
"number_of_sales__sum": 100
},
{
"name": "Репа",
"number_of_sales__sum": 400
}
]
Позволяет вычислить итоги по одним полям в разрезе других полей.
Отчет может быть:
Без итогов отчет представляет собой список всех полученных записей.
При расчете итогов формируется отчет с иерархической структурой в формате, представленном ниже.
{'results': Общие итоги,
'children': [{'results': Итоги по группе 1, 'children': [Записи принадлежащие группе 1]},
{'results': Итоги по группе 2, 'children': [Записи принадлежащие группе 2]}, ...]}
По умолчанию итоги рассчитываются только для групп. Для того чтобы дополнительно получить общие итоги, в параметр запроса results_by
необходимо передать параметр OVERALL
.
Для получения итогов, необходимо передать в параметр results
имя поля(полей) с указанием агрегатной функции.
И в параметр results_by
передать поля по которым необходима группировка для вычисления групповых итогов. (И/ИЛИ опциональный параметр OVERALL
)
Рассмотрим пример: Вам нужен список организаций, с общей выделенной для них суммой и групповыми итогами по типу организации общими итогами:
GET /organizations/?results=amount__sum&results_by=type,OVERALL
{'value__sum': 32.0, 'type': [{'type': 'ВУЗ', 'value__sum': 6.0,
'explanation': [{'id': 1, 'value': 1.0, 'name': 'ВУЗ 1'},
{'id': 2, 'value': 2.0, 'name': 'ВУЗ 2'},
{'id': 3, 'value': 3.0, 'name': 'ВУЗ 3'}]},
{'type': 'ДЦ', 'value__sum': 13.0,
'explanation': [{'id': 7, 'value': 6.0, 'name': 'ВУЗ 4'},
{'id': 8, 'value': 7.0, 'name': 'ВУЗ 5'}]},
]}
Позволяет предоставить отчет только для элементов подчиненным указанному (максимально возможной вложенности).
Для получения итогов, необходимо передать в параметр in_hierarchy
id объекта.
Рассмотрим пример: Вам нужен список организаций, подчиненных (по полю parent
) головной организации с id=1 и саму головную организацию:
GET /organizations/?in_hierarchy=1
[{'id': 8, 'name': 'ВУЗ 4', 'parent': 4},
{'id': 7, 'name': 'ВУЗ 3', 'parent': 4},
{'id': 4, 'name': 'ВУЗ 2', 'parent': 1},
{'id': 1, 'name': 'ВУЗ 1', 'parent': None}]
Фильтры для отчета можно установить составив выражение(я), в соответствии с синтаксисом.
[ИмяПоля] [Оператор выражения] [Значение]
Возможные значения Операторов выражения
перечислены в таблице ниже.
Оператор выражения | Псевдоним | Интерпретация | Field type requirements |
---|---|---|---|
== |
eq |
равно | - |
!= |
not eq |
не равно | - |
< |
lt |
меньше, чем | - |
> |
gt |
больше чем | - |
<= |
lte |
меньше или равно | - |
>= |
gte |
больше или равно | - |
contains |
поиск подстроки (с учетом регистра) | Только для текстовых полей | |
in |
В заданном списке | - | |
icontains |
поиск подстроки (без учета регистра) | Только для текстовых полей | |
isnull |
значение должно быть NULL | - |
Так же можно комбинировать несколько фильтров с помощью логических операторов and и or.
Описание | Фильтр |
---|---|
Пустой фильтр | |
Соответствие целочисленному полю | age == 32 |
Совпадение со значениями NULL | field_name isnull True |
Совпадение со значениями, отличными от NULL | field_name isnull False |
Связать несколько фильтров с помощью «and» | name = ‘Иннокентий’ and age >= 100 |
Связать несколько фильтров с помощью “or” | name = ‘Иннокентий’ or name = ‘Терентий’ |
Сопоставить имя поля, чтобы оно содержало подстроку “МЭИ” | name contains ‘МЭИ’ |
Поиск по текстовым полям можно установить с помощью параметра (search
).
/example/?search=организац
Сортировку можно установить с помощью параметра (sort
).
/example/?sort=id
Получение ответа с вложенными полями вынесенными в отдельную секцию можно получить задав параметр include
.
Вложенные объекты можно получить из секции include
по ключам соответствующим наименованиям объектов(параметр related_model_name
в OPTIONS запросе).
Для случая, когда необходимо вынести в отдельную секцию все объекты ссылочного типа, необходимо в параметре запроса include
установить значение all
.
Но, если Вам нужно вынести в секцию include
только одно/несколько вложенных полей, то в параметре include
необходимо перечислить эти поля.
Например, Вам нужен список статей(articles) и список комментариев к каждой статье:
/articles?include=comments — запрашиваем статью с комментариями
"results":
{
"data":
[
{
"id": 1
"title": "Статья 1"
"author": "Автор 1"
"comments": "1"
},
{
"id": 2
"title": "Статья 1"
"author": "Автор 1"
"comments": "2"
},
{
"id": 3
"title": "Статья 2"
"author": "Автор 2"
"comments": "3"
}
]
"include":
{
"Comments":
[
{
"id":1
"title": Комментарий 1
},
{
"id":2
"title": Комментарий 2
},
{
"id":3
"title": Комментарий 3
}
]
}
}
Для получения вложенных объектов глубиной более чем 1 уровень, необходимо в параметре include
указать вложенные поля с разделителем - точкой.
Например, include=comments.theme
- получаем во вложенной секции объекты темам комментариев.
В качестве модели для отчета рекомендуется использование абстрактной модели унаследованной от класса BaseReportModel
.
Библиотека предоставляет возможность создания виртуальных полей для моделей отчетов. Они нужны когда необходимо добавить в модель поля соответствующие набору каких-либо характеристик из табличных частей или других моделей. Виртуальные поля особенно полезны, когда количество характеристик является переменной величиной.
Для добавления виртуальных полей в модель отчета, необходимо использовать параметр virtual_fields
в метаклассе модели.
Параметр virtual_fields
содержит список объектов VirtualFields
, которые являются наследниками NamedTuple
и имеют
следующие параметры:
foreign_model
- Модель, данными из которой нужно дополнить модель.
Например, TabCatServiceCharacteristic
related_field
- наименование поля модели отчета образующее связь с моделью foreign_model
foreign_model_reference_field
- наименование поля модели foreign_model
образующее связь с полем related_field
characteristic_field
- Поле по значениям которого строятся виртуальные поля
Например, ‘characteristic__characteristic_type’
characteristic_value_field
- поле модели foreign_model, значения которого содержатся в виртуальных полях
Например, ‘characteristic’
subquery
- Опциональный параметр. Объект типа subquery (SQLAlchemy
). Содержит в себе подзапрос,
к модели foreign_model. Необходим для случая требующего особого поручения выборки (например СрезПоследних)
После добавления виртуальных полей в модель, они могут быть использованы как обычные поля для построения отчетов и запросов к данным.
Дополнение нулями - это процесс добавления недостающих значений в таблицу, чтобы каждый столбец содержал одинаковое количество строк по каждому уровню группировки. Вместо того, чтобы пропускать строки, где нет данных, мы заполняем их нулевыми значениями. Это может быть полезно для анализа данных, когда вам нужно сравнивать значения между столбцами с одинаковым количеством строк.
Для указания полей, по которым нужно добавить пустые значения, используется параметр запроса padding_zeros_fields
.
В качестве значения параметра передается список полей, разделенных запятой.
Пример использования механизма дополнения нулями может быть следующим: предположим, что у нас есть таблица, содержащая данные о продажах по различным магазинам в различных месяцах. Некоторые магазины не продали ничего в определенные месяцы, что привело к тому, что таблица содержит разное количество строк для каждого магазина и месяца. Чтобы анализировать данные на основе каждого месяца и каждого магазина, мы можем выполнить дополнение нулями, чтобы каждый столбец содержал одинаковое количество строк на каждом уровне группировки (месяц и магазин).