Migrating to Unified Report Views
Developer guide for the Enezaframework reporting engine. Part of the Add Report series.
Table of Contents
Overview
The legacy ReportView API still works, but new reports should inherit one unified
*ReportView base. The migration is mechanical: rename the base class, declare a
parameter_spec, and prefer registered computation field names over inline
ComputationField.create(...) calls.
flowchart LR
subgraph Legacy
RV["ReportView"] --> FK["Form auto-built from FK fields"]
RV --> CF["ComputationField.create(Sum, ...)"]
end
subgraph New
RT["TabularReportView"] --> PS["parameter_spec = ParameterSet(...)"]
RT --> REG["Registered name: '__total__'"]
end
RV -. migrate .-> RT
OLD["TabularReport + ReportEngineView"] -. deprecated .-> RTBefore and After
Before (legacy API):
python
from enezareporting.views import ReportView
from enezareporting.fields import ComputationField
from django.db.models import Sum
from myapp.models import SalesLine
class SalesReport(ReportView):
report_model = SalesLine
date_field = "date_placed"
group_by = "item_code"
columns = [
"item_description",
ComputationField.create(Sum, "value", name="total_sales", verbose_name="Total Sales"),
]
After (unified API):
python
from enezareporting.report_base import TabularReportView
from enezareporting.parameters import ParameterSet, DateRangeParam, FKFilterParam
from myapp.models import SalesLine
class SalesReport(TabularReportView):
report_model = SalesLine
date_field = "date_placed"
group_by = "item_code"
columns = [
"item_description",
"__total__", # registered computation field name
]
parameter_spec = ParameterSet(
DateRangeParam(name="date_range", start_field="date_placed"),
FKFilterParam(name="customer", model_field="customer"),
)
Key Changes
| Old | New |
|---|---|
Inherit ReportView |
Inherit a unified *ReportView base. |
Inherit TabularReport, ReportEngineView |
Inherit TabularReportView (deprecated form still works). |
| Form auto-built from FK fields | Form built from parameter_spec. |
ComputationField.create(Sum, "value", ...) |
Use a registered name such as "__total__", or import/define the field class. |
| No parameter declaration | Declare parameter_spec = ParameterSet(...). |
| Form factory only | Unified template + type-specific context. |
DesignTemplateMixin first in MRO |
Set design_slug on the unified base. |
TabularReportTotalsMixin |
Set add_totals = True and totals attributes. |
Computation Fields
Registered computation fields can be referenced by name
(enezareporting/fields.py):
python
columns = ["__total__", "__balance__", "__debit__", "__credit__"]
Define a custom field class, or create one on the fly:
python
from enezareporting.fields import ComputationField
from django.db.models import Sum, Avg
class AvgOrderValue(ComputationField):
name = "__avg_order__"
verbose_name = "Avg Order Value"
calculation_method = Avg
calculation_field = "value"
TotalWeight = ComputationField.create(
Sum,
"weight",
name="total_weight",
verbose_name="Total Weight",
)
ComputationField.create requires a unique name (enezareporting/fields.py:75-102).
Backward Compatibility
All existing classes continue to work:
ReportView,ModalReportView,ListReportView— unchanged.ReportEngineView— unchanged; the oldReportType + ReportEngineViewform is deprecated but still functional.DesignTemplateMixin,TabularReportTotalsMixin— unchanged compatibility shims.ReportGenerator,ListViewReportGenerator— unchanged.ReportGeneratorAPI,Chart— unchanged.ComputationField,field_registry— unchanged.- All existing template paths and tag names — unchanged.
See Report Views for the unified and legacy view tables.