Django Insights

Upgrading from 0.2

Version 0.3 is a big update, but your insights keep working. Most projects need the four steps below and take about ten minutes. Your collected data is kept.

What changed #

Area What changed Do you need to act?
Requirements Python 3.11 to 3.14, Django 5.2, 6.0 or 6.1 Yes, if you are older
Settings Three renamed, the chart colors replaced by INSIGHTS_THEME Yes
Database Two migrations for the insights database Yes, one command
Collecting One transaction, a failing insight now makes the command exit with an error Check your cron or CI
Permissions A permission class without has_permission now denies access Check your classes
PDF export Removed, with all its dependencies Yes, if you used it
Dashboard New design with Basecoat UI, light and dark Only if you override templates
New Trends, themes with 24 shadcn colors, 8 styles, system checks No, optional

Upgrade in four steps #

  1. Upgrade the package. You need Python 3.11 to 3.14 and Django 5.2, 6.0 or 6.1 (Django 6 needs Python 3.12+).

    pip install -U django-insights
    
  2. Rename your settings. The old names are ignored, manage.py check warns while they are still set.

    Old New
    INSIGHT_CHARTS_USE_MEDIA_CACHE INSIGHTS_CHARTS_USE_MEDIA_CACHE
    INSIGHT_MEDIA_CACHE_ROOT INSIGHTS_MEDIA_CACHE_ROOT
    INSIGHT_DASHBOARD_PERMISSIONS INSIGHTS_DASHBOARD_PERMISSIONS
    INSIGHTS_CHART_LIGHT_PRIMARY_COLOR, INSIGHTS_CHART_DARK_PRIMARY_COLOR INSIGHTS_THEME, see Theming
    INSIGHTS_THEME = "blue"  # a shadcn theme name, or {"accent": "#ec4899"}
    

    INSIGHTS_APP_NAME, INSIGHTS_CHART_DPI and INSIGHTS_DEFAULT_THEME are unchanged.

  3. Migrate the insights database. Two migrations, your data is kept.

    python manage.py migrate insights --database=insights
    
  4. Collect once and check.

    python manage.py collect_insights   # exit code 0
    python manage.py check              # no insights warnings
    

That is it for most projects. Read on for the changes that can affect you.

Things to check #

Permissions now fail closed

A class in INSIGHTS_DASHBOARD_PERMISSIONS without a has_permission(request) method used to be skipped, which granted access. It now raises ImproperlyConfigured and the dashboard denies access. Check that every class you list has the method and returns True for the people who should get in.

Cron jobs and CI see failures

collect_insights now runs in one transaction. When an insight raises, it is logged and reported, the others still run, and the command exits with an error such as 3 of 14 insights failed. A monitor that watches the exit code will start to report them.

PDF export is removed

Nothing replaces it. Remove links to insights:insight_pdf and insights:insight_pdf_test, and the [pdf] extra from your requirements. weasyprint, django-weasyprint and PyMuPDF are no longer used, and no system libraries (Pango and friends) are needed.

Old dashboard bookmarks

Dashboard URLs use a stable id per app, derived from the module path. Bookmarks of /app/<uuid>/ from 0.2 stop working once, collect again and use the new links.

What is new #

  • Trends on counters and gauges: a small line and the change against the previous period, see Trend.
  • Themes: pick a Basecoat style and shadcn colors, shared by the dashboard and the charts, see Theming.
  • System checks: manage.py check warns about a missing insights database, a wrong setting and more, see System checks.
  • Stable collecting: one transaction, per-insight errors, no output when it is not a terminal.
  • A pytest plugin that loads by itself, see Testing insights.

More details #

Settings behavior
  • Settings are read when they are used, so override_settings works. Unknown names raise AttributeError.
  • INSIGHTS_CHARTS_USE_MEDIA_CACHE = True requires INSIGHTS_MEDIA_CACHE_ROOT (insights.W003).
  • System checks are warnings only (insights.W001 to W012), they never stop the project from starting. django_insights.database.check_settings() is removed, run manage.py check.
The database migrations
  • 0002: labels are unique per app (two apps can both have count_users), Counter.value is a big integer, explicit ordering. The unused histogram type, the ExecutionDelta model and Gauge.gauge() are removed.
  • 0003: a trend column for counters and gauges.

The insights database is a cache of your data, so you can also delete it, migrate it again and run collect_insights.

Collecting from code
  • metrics.collect() returns the list of failures. It raises InsightsError (from django_insights.exceptions) when an insight saves duplicates, it no longer prints and calls exit().
  • The progress bar is hidden when the output is not a terminal.
  • The chart cache only deletes cached *-*-*.png files, it no longer wipes the whole media cache root.
Templates and static files

Only needed if you override templates or use the template tags yourself.

  • The dashboard is rebuilt with Basecoat UI. The templates under insights/ have a new structure (base.html, dashboard.html, app.html, _bucket.html, _stat.html, _empty.html). If you override any, start from the new ones, see Customizing.
  • {% chart bucket %} no longer takes an overlay argument. {% pdf_chart %} and pdf_available are removed, and so are the insights/pdf.html and pdf.css overrides.
  • Stylesheets are compiled per Basecoat style, icons are CSS classes and the Geist font is served from the package. Nothing is loaded from a CDN. Run collectstatic as usual.
  • The chart font is Geist (was Ubuntu). The library no longer changes matplotlib’s global configuration.
Using the library in code
  • The insights console script is removed (it never worked).
  • bar and hbar charts no longer crash when a category is None.
  • Only the names in __all__ of django_insights.metrics and django_insights.metrics_types are public.
Testing with the pytest plugin
  • The plugin loads through the pytest11 entry point, you do not need to register it.
  • The module-level registry, register_insights_modules and the injected fixture are removed. If you imported them from django_insights.pytest, use the insights_query fixture instead.
  • Errors inside an insights.py are no longer swallowed. The insights marker is registered, so --strict-markers works.
Building from source

Only for contributors.

  • uv build replaces flit. The version comes from the latest git tag (setuptools-scm).
  • pnpm install && pnpm build in django_insights/packages rebuilds the dashboard CSS.
  • ruff replaces black, isort and flake8, and tox runs through uv. Releases are made by pushing a tag.