Skip to main content

Django Slick Reporting

The one-stop reporting engine for Django — every report is one small declarative class.

PyPI version CI Python versions Django versions License Docs

Grouped totals, time series, crosstabs and charts — declared once, generated for you. Change one line of the class, get a totally different report.

pip install django-slick-reporting

Live Demo · Documentation · Quickstart


The shape of a report

A report is a small declarative class: every attribute maps to a visible part of the output. Watch what happens below as we change one line at a time — same SalesTransaction model throughout.

A group-by report

# 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()),
Product sales report grouped by product

Filter form, chart, sortable table and CSV export — all generated from the class.

Change one line → a different report

group_by accepts any field or relation path. Swap "product" for "client":

class ClientSales(ReportView):
    report_model = SalesTransaction
    date_field = "date"
    group_by = "client"   # ← the only change

    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"],
        ),
    ]
Same report regrouped by client

Same class, new grouping — a completely different report.

Add two lines → a monthly time series

class MonthlyProductSales(ReportView):
    report_model = SalesTransaction
    date_field = "date"
    group_by = "product"
    columns = ["name"]

    time_series_pattern = "monthly"  # ← new
    time_series_columns = [          # ← new
        ComputationField.create(
            Sum, "value",
            name="value__sum",
            verbose_name="Total sold $",
        ),
    ]

    chart_settings = [
        Chart(
            "Total sold $", Chart.LINE,
            data_source=["value__sum"],
            title_source=["name"],
        ),
    ]

"monthly" can be "daily", "weekly", "yearly" or a custom pattern.

Monthly time-series report

One column per month, computed per period.

Or pivot it → a crosstab matrix

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

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

    columns = [
        "name",
        "__crosstab__",
        ComputationField.create(
            Sum, "value",
            name="value__total",
            verbose_name="Total",
        ),
    ]
Crosstab matrix report

Products as rows, clients as columns, totals at the intersections.

More shapes — list views, custom querysets, precomputed crosstabs, time-series × crosstab combinations — in the documentation.


Charts, from the same class

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

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

Any other JS charting library can be plugged in as a custom engine.

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.

Ask the data — the LLM assistant

New: let your users ask questions in plain English and get an answer backed by a live report, with proofs. The assistant plans a report configuration, runs it through the same reporting engine, and answers with the numbers — you can inspect the generated report and the raw response right on the dashboard.

Ask the data: a plain-English question answered with a live report and proofs

Works with OpenRouter (free models included), any OpenAI-compatible endpoint, or a local llama.cpp server. Docs · Try it live

Features

  • Every report shape — simple aggregates, group-by, time-series, crosstab/pivot, and combinations of them.
  • Charts included — Highcharts, Chart.js and ApexCharts wrappers, plus pluggable custom engines.
  • 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.
  • Ask-the-data assistant — an optional LLM assistant answers plain-English questions with a generated report (docs).
  • 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

The group-by report above is a complete working example — declare the class, wire one URL, done. Prefer data without a view? The same configuration works on the low-level engine:

from slick_reporting.generator import ReportGenerator

report = ReportGenerator(
    report_model=SalesTransaction,
    group_by="product",
    columns=["name", "__total__"],
)
report.get_report_data()
# -> [{'name': 'Product 1', '__total__': 56}, {'name': 'Product 2', '__total__': 43}, ...]

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

To try the Ask the data assistant, put an OpenRouter key in the OPENROUTER_API_KEY environment variable (a demo_proj/.env file works too). The demo defaults to the free-tier model nex-agi/nex-n2.5-mini:free; switch models with the SLICK_REPORTING_LLM_MODEL environment variable — e.g. SLICK_REPORTING_LLM_MODEL=google/gemma-4-31b-it:free python manage.py runserver. Browse free models at openrouter.ai/models.

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 git@github.com: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

Metadata

Release files for django-slick-reporting 1.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-slick-reporting 1.5.0
File Size Uploaded
django_slick_reporting-1.5.0.tar.gz 64.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-slick-reporting 1.5.0
File Interpreter ABI Platform
django_slick_reporting-1.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 142.4 kB

Release files / django_slick_reporting-1.5.0.tar.gz

Download URL django_slick_reporting-1.5.0.tar.gz
Size 64.3 kB
Tags Source
SHA-256 checksum
How to use checksums
0f091439a42ad74a3c23bc277f73a86f17301a27b4d41451a1fae08459dd7181
BLAKE2b-256 checksum
How to use checksums
c27ab0e32144bde58049bec785fe8c0302cd4b3503886047a7d2448e36a8861c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / django_slick_reporting-1.5.0-py3-none-any.whl

Download URL django_slick_reporting-1.5.0-py3-none-any.whl
Size 78.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1fc369f3cf011c0491d90767668640e44be56370d3ecbed864c4f0484a9fe261
BLAKE2b-256 checksum
How to use checksums
76f0eb022f838c451769b27623889ede872999207f40f4ced4692598fa24750d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.5.0 This release

2 release files

1.4.0

2 release files

1.3.1

1 release file

1.3.0

1 release file

1.2.0

1 release file

1.1.1

1 release file

1.1.0

1 release file

1.0.2

1 release file

1.0.1

1 release file

1.0.0

1 release file

0.9.0

1 release file

0.8.0

1 release file

0.7.0

1 release file

0.6.8

1 release file

0.6.7

1 release file

0.6.6

1 release file

0.6.5

1 release file

0.6.4

1 release file

0.6.3

1 release file

0.6.2

1 release file

0.6.1

1 release file

0.6.0

1 release file

0.5.8

1 release file

0.5.7

1 release file

0.5.6

1 release file

0.5.5

1 release file

0.5.4

1 release file

0.5.3

1 release file

0.5.2

1 release file

0.5.1

1 release file

0.5.0

1 release file

0.4.2

1 release file

0.4.1

1 release file

0.4.0

1 release file

0.3.0

1 release file

0.2.9

1 release file

0.2.8

1 release file

0.2.7

1 release file

0.2.6

1 release file

0.2.5

1 release file

0.2.4

1 release file

0.2.3

1 release file

0.2.2

1 release file

0.2.1

1 release file

0.1.5

1 release file

0.1.4

1 release file

0.1.3

1 release file

0.1.2

1 release file

0.1.1

1 release file

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page