Report Types Overview
Developer guide for the Enezaframework reporting engine. Part of the Add Report series.
Table of Contents
- Overview
- The Unified Base Hierarchy
- Common Attributes
- Choosing a Report Type
- How a Report Type Is Registered
- Required-Attribute Validation
- Related Guides
Overview
Every report is built from a unified report base in
enezareporting.report_base — a single class that declares the shape of the report and
already includes the view, designer rendering, query-builder filters, and totals hooks.
Inherit exactly one base:
from enezareporting.report_base import TabularReportView
class MyReport(TabularReportView):
...
The pure type classes in enezareporting.report_types remain the metadata and validation
layer used internally. See Report Views.
The Unified Base Hierarchy
classDiagram
class BaseReportView {
<<abstract>>
+report_model
+parameter_spec
+columns
+design_slug
+add_totals
}
class TabularReportView
class SummaryReportView
class DetailedReportView
class CrosstabReportView
class TimeSeriesReportView
class DrillDownReportView
class DocumentReportView
class BaseDocumentReport
BaseReportView <|-- TabularReportView
BaseReportView <|-- CrosstabReportView
BaseReportView <|-- TimeSeriesReportView
BaseReportView <|-- DrillDownReportView
TabularReportView <|-- SummaryReportView
TabularReportView <|-- DetailedReportView
BaseDocumentReport <|-- DocumentReportView| Unified base | Layout | Default parameters | Dedicated guide |
|---|---|---|---|
DocumentReportView |
Header + lines + totals | DocumentParam("document_id") |
Document Reports |
TabularReportView |
Rows + aggregates | DateRangeParam("date_range") |
Tabular Reports |
SummaryReportView |
Aggregates only, no detail rows | inherited from TabularReportView |
Tabular Reports |
DetailedReportView |
Full granular rows, no aggregation | inherited from TabularReportView |
Tabular Reports |
CrosstabReportView |
2D pivot | none (add your own) | Crosstab Reports |
TimeSeriesReportView |
Chronological buckets | none (add your own) | Time Series Reports |
DrillDownReportView |
Hierarchical levels | empty ParameterSet() |
Drill-Down Reports |
Common Attributes
These attributes are available on every unified base (inherited from the metadata layer in
enezareporting/report_types.py and the view layer in enezareporting/views.py):
| Attribute | Type | Purpose |
|---|---|---|
report_model |
model class | The main Django model for the report. |
parameter_spec |
ParameterSet |
Filter parameters used to build the form. |
generator_class |
class | Overrides the generator chosen by the view. |
columns |
list | Column definitions: field names, computation names, or callables. |
chart_settings |
list | Optional chart configuration. |
template_blocks |
dict | Maps template block names to overrides. |
queryset |
queryset | Optional pre-filtered queryset. |
table_name |
str | If set, a dynamic model is created from this DB table. |
auto_discover_filters |
bool | Build the form from the model schema. |
date_field |
str | Date field used for date-range filtering. |
group_by |
str | Field rows are grouped by. |
report_title |
str | Display title (defaults to the class name). |
report_slug |
str | URL/identifier slug. |
report_name |
str | Name segment used by document-report URL generation. |
context_variables |
list | Extra context values. |
swap_sign |
bool | Swap debit/credit sign handling. |
limit_records |
int | Cap the number of records returned. |
default_order_by |
str | Default result ordering. |
design_slug |
str | Report designer layout slug; rendering is built into every unified base. |
add_totals |
bool | Append a totals row; set totals_group_column and line_total_fields too. |
use_query_builder |
bool | Enable the query-builder filter UI. |
dashboard_enabled |
bool | Opt the report in as a dashboard data source. |
ReportEngineViewremains available for advanced/legacy use and can take an explicitreport_type_classattribute. Unified bases read the type metadata directly from the class.
Choosing a Report Type
flowchart TD
START[What does the report show?] --> H{Lines of a single\ndocument?}
H -->|Yes| DOC[DocumentReportView]
H -->|No| PIVOT{2D pivot by a field?}
PIVOT -->|Yes| CROSS[CrosstabReportView]
PIVOT -->|No| TIME{Buckets over time?}
TIME -->|Yes| TS[TimeSeriesReportView]
TIME -->|No| HIER{Drill into levels?}
HIER -->|Yes| DD[DrillDownReportView]
HIER -->|No| GROUP{Aggregated rows?}
GROUP -->|Summary only| SUM[SummaryReportView]
GROUP -->|Detail rows only| DET[DetailedReportView]
GROUP -->|Grouped + totals| TAB[TabularReportView]How a Report Type Is Registered
ReportTypeMeta registers every concrete unified base subclass in the
report_type_registry (enezareporting/registry.py:35-47). Abstract bases such as
TabularReportView and DocumentReportView are skipped.
class ReportTypeMeta(ABCMeta):
def __new__(mcs, name, bases, namespace):
cls = super().__new__(mcs, name, bases, namespace)
if name == "ReportType":
return cls
mcs._validate(cls)
if has_legacy_report_engine_base(bases):
warnings.warn("... use the unified *ReportView base ...")
if not namespace.get("__abstract__", False):
report_type_registry.register(cls)
return cls
Registering makes the type discoverable by name:
report_type_registry.get_by_name("myapp.reports.SalesReport").
Required-Attribute Validation
Several unified bases validate themselves at class-creation time via
__init_subclass__ and raise django.core.exceptions.ImproperlyConfigured when a required
attribute is missing. Abstract bases are skipped until a concrete report class is defined:
| Base | Required attributes |
|---|---|
DocumentReportView |
header_fields, line_columns (when header_model is set) |
CrosstabReportView |
crosstab_field, crosstab_columns |
TimeSeriesReportView |
time_series_pattern, time_series_columns, date_field |
DrillDownReportView |
hierarchy (non-empty) |
DrillDownReportView clamps max_depth to the size of the hierarchy with
min(max_depth, len(hierarchy)).