Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Django QBE 2

A reusable Django app for building authorized reports without writing SQL. Choose columns, add typed conditions, follow model relationships, preview paginated results, build grouped summaries, export CSV or Excel, and email scheduled snapshots. Supports Python 3.13–3.14 and Django 6.0–6.1.

Documentation: Installation, usage, report registration, relationships and more.

Experimental alpha: this is the initial implementation, not a production release or a drop-in replacement for the original package. The current release candidate is 0.1.0a15; check PyPI for its availability. Inspired by versae/qbe, rebuilt around Django's ORM, explicit permissions and typed query definitions.

Try the demo

From a checkout containing this implementation:

uv sync --python 3.14 --frozen --group dev
uv run python demo/manage.py migrate
uv run python demo/manage.py seed_demo
uv run python demo/manage.py changepassword qbe2_demo_alice
uv run python demo/manage.py runserver 127.0.0.1:8000

Open the report builder and log in as qbe2_demo_alice with the password you chose. The seed creates six synthetic customers and 24 orders for two users. Each user can view only their own records. It never sets a shared password or overwrites an existing non-demo account. An optional superuser created with createsuperuser can inspect all demo records.

Install in another project

In your project's virtual environment, install the explicit alpha version after checking its availability on PyPI:

python -m pip install django-qbe2==0.1.0a15

For Excel workbooks as well as CSV, install the optional extra:

python -m pip install 'django-qbe2[excel]'

To try the checkout before publication, build and install its wheel:

uv build
python -m pip install /absolute/path/to/dist/django_qbe2-0.1.0a15-py3-none-any.whl

Add the app and mount its namespaced URLs alongside Django Admin:

# Keep your existing Django apps, including admin, auth, sessions and messages.
INSTALLED_APPS += ["django_qbe2"]
from django.urls import include, path

# Keep your existing admin URL and other routes.
urlpatterns += [path("qbe/", include("django_qbe2.urls"))]

Keep standard authentication, sessions and CSRF middleware, APP_DIRS template discovery and the admin context processors. Serve the packaged assets with your usual Django static-file setup. Run python manage.py migrate to create saved-query and scheduled-report tables when using a release that includes those features. The catalog is empty until you register reports.

Register reports and their policies

Create qbe.py in your own installed app. Modules are discovered at startup, without fetching report data. Register related targets as well as root models:

from django_qbe2.registry import Report, register
from .models import Customer, Order


@register
class CustomerReport(Report):
    model = Customer
    fields = ("name",)

    def get_queryset(self, request):
        return Customer.objects.filter(owner=request.user)


@register
class OrderReport(Report):
    model = Order
    fields = ("number", "customer__name", "total", "status")
    field_labels = {"customer__name": "Customer", "total": "Total amount"}

    def get_queryset(self, request):
        return Order.objects.filter(owner=request.user)

Users need active staff status and Django view permissions for the root and any related model used. Staff status alone does not grant report access. Every report must provide an explicit row policy; Django model permissions do not imply row authorization. The same policies apply to columns, filters, ordering, HTML, CSV and Excel.

Django model choices require no QBE-specific configuration. Register the field, and equality filters offer its options automatically. The complete documentation example defines an Order status using TextChoices. Adapt the example's fields and ownership policy to your own models; owner is not a required field name.

For saved queries and scheduled reports, run python manage.py migrate after upgrading. Preview a report to save its definition, then use Saved queries to reopen it or manage named recipients. Sharing never grants model permissions or access to the creator's rows. See the saved-query guide and roadmap. Condition groups preserve existing saved definitions and require no additional migration. Summary definitions use the same storage, sharing and current-user authorization rules.

What is included

  • Text, integer, decimal, boolean, date, datetime and UUID fields.
  • Generic model-choice selectors and readable HTML labels; exports keep stored codes.
  • Saved definitions, private by default, with explicit reader/copy sharing.
  • Bounded nested AND/OR/NOT groups, ascending/descending order and stable pagination.
  • Grouped or ungrouped Count, Sum and Average reports over authorized source rows.
  • Up to two relationship hops, including reverse and ManyToMany relations, with explicit related-row authorization and bounded collection columns.
  • Bounded CSV streaming, exact decimals, Unicode and safe text formula handling.
  • Optional Excel workbooks for row and summary reports, with typed cells and safe text.
  • Owner-only daily/weekly schedules that email complete bounded reports through Django's configured mailer; see the scheduled-report guide.
  • Django Admin styling, light/dark modes and responsive, keyboard-accessible controls.

Database-native aggregates run in the database. Arbitrary joins, multi-database selection, public APIs and group sharing need separate design. Excel export requires the optional excel dependency: python -m pip install 'django-qbe2[excel]'. CSV uses a synchronous streaming iterator intended for WSGI deployment. Sources are plain English reStructuredText under docs/source, readable by developers and agents. Contributor instructions live in AGENTS.md.

Build the documentation

uv sync --python 3.14 --frozen --group dev --group docs
uv run --group docs sphinx-build -n -W -b html docs/source docs/_build/html
uv run --group docs sphinx-build -n -W -b text docs/source docs/_build/text
python -m http.server 8001 --bind 127.0.0.1 --directory docs/_build/html

Open http://127.0.0.1:8001/. Sphinx is a documentation dependency only. CI checks HTML and plain-text builds with warnings treated as errors. The published documentation is available at carocha.github.io/django-qbe2.

License and attribution

MIT, copyright Carlos A. Rocha. The project acknowledges Javier de la Rosa and the contributors to versae/qbe as its inspiration. The current code is a new implementation; preserve upstream notices if you reuse upstream code in a future change.

Metadata

Release files for django-qbe2 0.1.0a15

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-qbe2 0.1.0a15
File Size Uploaded
django_qbe2-0.1.0a15.tar.gz 61.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-qbe2 0.1.0a15
File Interpreter ABI Platform
django_qbe2-0.1.0a15-py3-none-any.whl Python 3 none any Details

Total release size: 147.2 kB

Release files / django_qbe2-0.1.0a15.tar.gz

Download URL django_qbe2-0.1.0a15.tar.gz
Size 61.7 kB
Tags Source
SHA-256 checksum
How to use checksums
03b1d713a0688e1d7357bd71427a7df3275fc3133044f33efc9022bb20ffd215
BLAKE2b-256 checksum
How to use checksums
7d9f6881f69d0038222ed262ac45b51f0edf53377e1879e5864bc16d47b5d03a
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 16, 2026.

Transparency log

Release files / django_qbe2-0.1.0a15-py3-none-any.whl

Download URL django_qbe2-0.1.0a15-py3-none-any.whl
Size 85.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9f0e13935b95c556cafb5b6b75977e33da0fbfab86effe0081aa72d77080f6ba
BLAKE2b-256 checksum
How to use checksums
b12a46d87939b511e2046fee13bc59cd2115a385d9008fcbe8a0fb0412a36cbe
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 16, 2026.

Transparency log
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