RamezIssac/django-slick-reporting

The Reporting Engine for Django. Create dashboards and standalone Reports and Charts.

analysis
analytics
charting
charts
customisable
django
easy-to-use
pivot-tables
python
reporting
time-series
# Django Slick Reporting ### The one-stop reporting engine for Django — analytics, charts & dashboards in a few lines of code. [![PyPI version](https://img.shields.io/pypi/v/django-slick-reporting.svg)](https://pypi.org/project/django-slick-reporting) [![Python versions](https://img.shields.io/pypi/pyversions/django-slick-reporting.svg)](https://pypi.org/project/django-slick-reporting) [![Docs](https://img.shields.io/readthedocs/django-slick-reporting)](https://django-slick-reporting.readthedocs.io/) [![Coverage](https://img.shields.io/codecov/c/github/ra-systems/django-slick-reporting)](https://codecov.io/gh/ra-systems/django-slick-reporting) [![License](https://img.shields.io/pypi/l/django-slick-reporting.svg)](https://github.com/ra-systems/django-slick-reporting/blob/develop/LICENSE.md) Grouped totals, time-series, crosstabs and pivots — each one a small Python class, each one chartable with a single line, in **Highcharts, Chart.js or ApexCharts**. [**Live Demo**](https://django-slick-reporting.com/) · [**Documentation**](https://django-slick-reporting.readthedocs.io/) · [**Quickstart**](#quickstart) Django Slick Reporting dashboard

One report class, every chart

Declare the calculation once. Switch the visualization by changing a single argument — no new query, no new template.

Switching chart types by changing one argument

Why Django Slick Reporting?

  • Every report shape — simple aggregates, group-by, time-series, crosstab/pivot, and combinations of them.
  • Charts included — Highcharts, Chart.js and ApexCharts wrappers. Bar, column, line, area, pie — stacked or totalled — from one Chart(...) line.
  • Custom calculations — build reusable computation fields, chain dependencies, compute percentages and balances.
  • Dashboards — drop any report onto a page as a self-contained widget with a template tag.
  • Model-optional — report against a Django model, a traversed relation, a raw SQL table, or precomputed/aggregated data.
  • Fast & extendable — optimized queries, CSV export out of the box, and hooks for everything.

Installation

pip install django-slick-reporting

Add it to INSTALLED_APPS and you're ready:

INSTALLED_APPS = [
    ...,
    "crispy_forms",
    "crispy_bootstrap5",
    "slick_reporting",
]

Quickstart

Given a typical SalesTransaction model, here is a group-by report — total value sold per product — with a bar chart:

# views.py
from django.db.models import Sum
from slick_reporting.views import ReportView, Chart
from slick_reporting.fields import ComputationField
from .models import SalesTransaction


class ProductSales(ReportView):
    report_model = SalesTransaction
    date_field = "date"
    group_by = "product"

    columns = [
        "name",
        ComputationField.create(
            Sum, "value", name="value__sum",
            verbose_name="Total sold $",
        ),
    ]

    chart_settings = [
        Chart(
            "Total sold $",
            Chart.BAR,
            data_source=["value__sum"],
            title_source=["name"],
        ),
    ]
# urls.py
path("product-sales/", ProductSales.as_view()),
Group-by bar chart result

That's the whole report — filter form, chart, sortable data table and CSV export are generated for you.

Same data, any visualization

The chart is just configuration. Keep the report, change the Chart(...) line:

Chart(
    "Sales",
    Chart.BAR,
    data_source=["value__sum"],
    title_source=["name"],
)
Bar chart
Chart(
    "Sales",
    Chart.PIE,
    data_source=["value__sum"],
    title_source=["name"],
    plot_total=True,
)
Pie chart

…and any chart engine

Set chart_engine on the report (or per Chart). The same data renders through your engine of choice:

Highcharts
chart_engine="highcharts"
Chart.js
chart_engine="chartsjs"
ApexCharts
chart_engine="apexcharts"
Highcharts Chart.js ApexCharts

Report types

Time series — one column per period (daily / weekly / monthly / yearly / custom)
class MonthlyProductSales(ReportView):
    report_model = SalesTransaction
    date_field = "date"
    group_by = "product"
    columns = ["name", "sku"]

    time_series_pattern = "monthly"          # daily / weekly / yearly / custom
    time_series_columns = [
        ComputationField.create(Sum, "value", name="value", verbose_name="Sales"),
    ]

    chart_settings = [
        Chart("Sales Monthly", Chart.COLUMN, data_source=["value"], title_source=["name"]),
    ]
Calculations are performed for each period and laid out as repeating columns, with an optional grand-total column.
Crosstab / Pivot — matrix reports with rows, columns and intersecting totals
class ClientProductMatrix(ReportView):
    report_model = SalesTransaction
    group_by = "client"
    crosstab_field = "product"
    crosstab_columns = [
        ComputationField.create(Sum, "value", verbose_name="Value"),
    ]
    crosstab_compute_remainder = True         # a column capturing "everything else"

    columns = [
        "name",
        "__crosstab__",                       # where the matrix columns land
        ComputationField.create(Sum, "value", verbose_name="Total Value"),
    ]
Crosstab matrix report
Crosstab and time-series can even be combined for a matrix over periods. Already-aggregated data? Set `crosstab_precomputed=True`.
List view — ungrouped, row-level data
from slick_reporting.views import ListReportView

class LastTenSales(ListReportView):
    report_model = SalesTransaction
    date_field = "date"
    columns = ["product__name", "client__name", "date", "quantity", "value"]
    default_order_by = "-date"
    limit_records = 10
Low-level engine — get raw data without a view
from slick_reporting.generator import ReportGenerator

report = ReportGenerator(
    report_model=SalesTransaction,
    group_by="product",
    columns=["title", "__total__"],
)
report.get_report_data()
# -> [{'title': 'Product 1', '__total__': 56}, {'title': 'Product 2', '__total__': 43}, ...]
`ReportView` is a thin wrapper over `ReportGenerator` — the same configuration syntax works in both.

Dashboards

Compose any report into a page as a self-contained widget — chart, table, or both — with one template tag:

{% load slick_reporting_tags %}

{% get_widget_from_url url_name="product-sales" %}
{% get_widget_from_url url_name="monthly-product-sales" chart_id=1 display_table=False title="Chart only" %}

See the live dashboard example.

Demo site

Live at django-slick-reporting.com, or run it locally:

git clone https://github.com/ra-systems/django-slick-reporting.git
python -m venv .venv && source .venv/bin/activate

cd django-slick-reporting/demo_proj
pip install -r requirements.txt
python manage.py migrate
python manage.py create_entries   # generates demo data
python manage.py runserver

Documentation

Full documentation lives on Read the Docs. Build it locally with:

cd docs
pip install -r requirements.txt
sphinx-build -b html source build

Running the tests

git clone [email protected]:ra-systems/django-slick-reporting.git
cd django-slick-reporting/tests
python -m pip install -e ..
python runtests.py
# coverage:
coverage run --include=../* runtests.py && coverage html

Contributing

PRs and reviews are most welcome. We follow Django's contributing guidelines. If the project is useful to you, please consider giving it a star — it keeps the project visible and motivated.

Authors

You might also like

Stars
600
-0.17% more than last month
Forks
48
Open Issues
23