Dashboard Reference

Complete configuration reference for the Enezaframework dashboard system. Part of the Dashboards series.

Table of Contents

  1. A. Report Class Attributes
  2. B. Identifiers and Permissions
  3. C. Eligibility Rules
  4. D. Report Metadata Contract
  5. E. Definition Schema
  6. F. Widget Configuration
  7. G. Layout and Widget Limits
  8. H. Parameters, Filters, and Periods
  9. I. Settings
  10. J. Routes
  11. K. Error Codes
  12. Related Guides

A. Report Class Attributes

These attributes are declared on a report class. The base defaults come from the metadata layer in enezareporting/report_types.py and the unified bases in enezareporting/report_base.py.

Core report attributes

Attribute Type Default Purpose
report_model model class None Model the report reads. Required for a dashboard source unless get_report_model() resolves one.
columns list [] Field names, computation fields, and callables to expose. Drives dimensions, measures, tables, and previews.
group_by str or tuple "" Field(s) used for grouping. Grouped fields must also be in columns to be widget dimensions.
date_field str "" Date field used for date-range filtering and dashboard periods.
parameter_spec ParameterSet empty Declares the report's filter form fields.
report_generator_class class ReportGenerator Generator used by the view. frameworkapp uses ListViewReportGenerator.
report_name str "" Human title. Dashboard title falls back to report_title, then the class name.
report_title str "" Page title; used as a dashboard title fallback.
report_slug str "" Stable slug. Defaults to the lowercased class name.
report_app_label str "" App-label fallback. Avoid setting it when report_model exists: get_dashboard_code() prefers it, while discovery's meta.app_label prefers the model, which can split the URL/report code from the permission code.
queryset queryset None Optional base queryset.
limit_records int None Optional row cap on the report itself.
default_order_by str "" Default report ordering.
swap_sign bool False Report-specific debit/credit sign handling.
context_variables list [] Designer/context variables; not used by dashboard execution.

Dashboard opt-in attributes

Attribute Type Default Purpose
dashboard_enabled bool False Required opt-in. Without it the report is never a data source.
dashboard_code str "" Overrides the stable report_ref. Does not change the output permission.
report_url_name str "" URL name used by the widget's View report link.
dashboard_entity_scoped bool False Calls queryset.for_entity(request=request) when the entity and method exist.
use_query_builder bool False Enables dashboard query-builder filter metadata.
use_modal_filter bool False Report-page UI behavior; not used by dashboards.

Class methods

Method Returns Notes
get_dashboard_code() str dashboard_code, or <app_label>.<slug>.
get_dashboard_title() str report_name, report_title, or class name.
get_dashboard_url_name() str report_url_name or empty.
get_report_model() model class Optional override for report_model.

Computation fields

python
from django.db.models import Sum
from enezareporting.fields import ComputationField

TotalValue = ComputationField.create(
    Sum,
    "value",
    verbose_name="Total Value",
)
  • The generated column name is <method>__<field> when no name is supplied, for example sum__value (enezareporting/fields.py:76-99).
  • A computation field becomes a measure with one supported aggregation: the method name (enezareporting/dashboard.py:238-278).
  • The class attribute (TotalValue) is exposed as an alias, but canonical column names are safer in definitions.

B. Identifiers and Permissions

Code derivation

From enezareporting/dashboard.py and enezareporting/report_types.py:

text
# get_dashboard_code()
code_app_label = report_app_label
                 or report_model._meta.app_label
                 or report_class.__module__.split(".")[0]

# discovery metadata
meta_app_label = report_model._meta.app_label
                 or report_app_label
                 or report_class.__module__.split(".")[0]

report_slug = get_report_slug()
              or report_slug
              or report_class.__name__.lower()

report_ref = dashboard_code or f"{code_app_label}.{report_slug}"

output_code = f"output.{meta_app_label}.{report_slug}.view"

Consequences:

  • Do not set report_app_label when report_model exists. The two app labels above can disagree, producing a report_ref that does not match the permission code.
  • dashboard_code changes report_ref only. The RBAC permission still follows report_slug.
  • Duplicate report_ref values raise ImproperlyConfigured during discovery (enezareporting/dashboard.py:345-353).
  • report_url is reverse(report_url_name). An unreversible name leaves the URL blank but does not make the report ineligible (enezareporting/dashboard.py:197-202).

Permission

Every widget execution calls:

python
has_output_permission(user, source.meta.output_code, request=request)

If the permission is missing, the widget returns a report_forbidden error and the report is removed from the page's filter groups (enezareporting/dashboard.py:501-527, enezadashboard/services/renderer.py:156-180).

Run python manage.py rbac_sync after adding or renaming reports.


C. Eligibility Rules

A source is returned by discovery only if all conditions pass (enezareporting/dashboard.py:204-217, enezareporting/dashboard.py:332-355).

Condition Required state
Concrete report class Not __abstract__, name does not start with _.
Registered Imported at startup and present in report_type_registry.
Opted in dashboard_enabled = True.
Supported type TabularReportView / SummaryReportView / DetailedReportView, not crosstab, time-series, document, or drill-down.
Resolvable model report_model or get_report_model() returns a model.
Parseable columns check_columns(...) completes without raising.
Unique code No other report produces the same report_ref.
User permission output.<app_label>.<report_slug>.view granted, when listing for a user.

Ineligible reports are excluded silently. The internal reason string is stored on the source metadata but never shown in discovery results.


D. Report Metadata Contract

DashboardReportMeta.to_dict() returns these keys (enezareporting/dashboard.py:50-90):

Key Type Contents
code str Stable report_ref.
title str Display title.
description str Report description.
app_label str Owning app label.
report_type str "tabular" for dashboard-supported reports.
model_label str "<app_label>.<model_name>".
output_code str RBAC permission code.
report_url_name str URL name, possibly empty.
report_url str Reversed URL, possibly empty.
columns list Column descriptors.
dimensions list[str] Database column names usable as categories/series.
measures list Numeric/computation descriptors.
parameters list Serialized report parameters.
filter_fields list[str] Allowed query-builder field IDs.
filter_schema dict Raw filter schema keyed by model.
eligible bool Eligibility state.
ineligible_reason str Why the report is ineligible, when applicable.

Column descriptor

Key Meaning
name Canonical column name. Use this in widget config.
label Human label from verbose_name.
type Django internal field type for database columns, or the computation field's declared type (number by default).
format Report formatting hint.
align left, right, or the generator's alignment.
is_summable Whether the report marks it summable.
is_computation True for computation fields.
computation_field Underlying model field for computation fields.
aggregations Supported aggregation names.
aliases Canonical name, computation name, and unique class attribute alias.
source database or magic_field.

Measure descriptor

Key Meaning
name Canonical column name.
label Human label.
aggregations Supported aggregation names.
aliases Accepted aliases.

Numeric database fields support sum, avg, min, max, count. Computation fields support their own method name only.

Abridged example

The exact values depend on the report class; the shape is:

json
{
  "code": "frameworkapp.frameworktestdocumentsales",
  "title": "Framework Test Document Sales",
  "app_label": "frameworkapp",
  "report_type": "tabular",
  "model_label": "frameworkapp.frameworktestdocumentline",
  "output_code": "output.frameworkapp.frameworktestdocumentsales.view",
  "report_url_name": "frameworkapp:frameworktestreport",
  "report_url": "/frameworkapp/frameworktestreport/",
  "columns": [
    {
      "name": "sum__item_quantity",
      "label": "Total Quantity",
      "type": "number",
      "format": "number",
      "align": "right",
      "is_computation": true,
      "computation_field": "item_quantity",
      "aggregations": ["sum"],
      "aliases": ["sum__item_quantity", "SumItemQuantity"],
      "source": "magic_field"
    }
  ],
  "dimensions": ["item_code", "item_description"],
  "measures": [
    {
      "name": "sum__item_quantity",
      "label": "Total Quantity",
      "aggregations": ["sum"],
      "aliases": ["sum__item_quantity", "SumItemQuantity"]
    }
  ],
  "parameters": [
    {
      "name": "date_range",
      "label": "Date Range",
      "type": "date_range",
      "required": false,
      "start_field": "created_at",
      "end_field": "created_at",
      "form_fields": ["start_date", "end_date"]
    }
  ],
  "filter_fields": ["item_code", "item_description"],
  "filter_schema": {},
  "eligible": true,
  "ineligible_reason": ""
}

Use the metadata endpoint to inspect the real values:

text
/dashboards/manage/report-meta/?report=frameworkapp.frameworktestdocumentsales

E. Definition Schema

Dashboard definition

Key Required Default Notes
module Yes — Installed app label. Filled from an AppConfig source when omitted.
code Yes — Valid slug, unique with module.
name Yes — Display name.
description No "" Long description.
is_active No True Visibility.
is_default No False One active default per module.
sort_order No 0 Ordering.
managed_by No "seed" seed or admin.
layout_template No "" Known wireframe code; provenance only.
default_report_ref No "" Eligible report code.
access_code No "" Optional RBAC permission.
seed_revision No "" Stored marker.
publish No New: true Publish after seeding.
tabs No [] Tab definitions.
data_settings — — Not read by seeding. Use the designer.

Tab definition

Key Required Default Notes
code Yes — Unique within the version.
name Yes — Display name.
description No "" Description.
icon No "" Must be in TAB_ICON_KEYS for seeded definitions; the designer offers only those choices.
sort_order No 0 Ordering.
layout No {} Stored layout metadata.
filter_config No {} date_range, data, parameter_defaults.
widgets No [] Widget definitions.

Widget definition

Key Required Default Notes
code Yes — Unique within the tab.
title Yes — Display title.
type / widget_type Yes — kpi, chart, table, report_preview.
report_ref Yes — Eligible data source.
description No "" Supporting text.
display_config No {} Type-specific configuration.
layout No By type x, y, w, h.
parameter_config No {} Allowed report parameter values.
filter_config No {} Query-builder rules.
sort_order No 0 Ordering.
is_active No True Inactive widgets are skipped.

Unknown keys are ignored by the seeder. They do not raise an error, so a typo in an optional key can silently do nothing. Validate with --dry-run and inspect the resulting draft.


F. Widget Configuration

All widget keys live under display_config. Validation code:

KPI

Key Type Default Rules
measure str "" Must be a report column/alias. Required unless aggregation is count. For numeric results it should be a measure.
aggregation str auto sum, avg, min, max, count, or empty. When the measure descriptor is found, the value must be one of its aggregations.
format str number number, currency, percent, integer, text, or empty.
decimals int 0 0–6.
prefix str "" Prepended to the formatted value.
suffix str "" Appended to the formatted value.
sparkline object none {category_field, value_field, limit}. Limit 2–60, default 24. Both fields must exist on the report.
percent_is_fraction bool true Definition-only. When true, percent values are multiplied by 100.

Behavior:

  • Formatting is done by format_metric() (enezadashboard/widgets/base.py:61-81).
  • integer and text use the same numeric formatting path as number; they do not coerce values to strings.
  • currency does not imply two decimals. Set decimals: 2 explicitly; the form default is 0.
  • The KPI compares against the previous period or previous year automatically when the page has comparison enabled and the report supports dates.
  • A sparkline runs a query over the report rows and renders an SVG; it is not a client-side chart.

Chart

Key Type Default Rules
chart_type str bar One of the 16 types below.
category_field str "" Required except for gauge. Must be a report column/alias. Numeric for scatter and bubble.
value_field str "" Required except for gauge. Must be a numeric measure.
series_field str "" Required for heatmap, stacked_bar, stacked_area. Must be a column.
line_field str "" Required for combo. Must be a numeric measure.
size_field str "" Required for bubble. Must be a numeric measure.
comparison_field str "" Optional. Used by line, area, combo, and radar; when set, must be a numeric measure.
measure str "" Gauge only. Alternative to value_field. Must be a numeric measure.
aggregation str sum Gauge only. sum, avg, min, max, or count.
target number none Target line for line/area, or target value for gauge/bullet. Numeric.
scale_max number none Gauge/bullet maximum. Numeric and greater than zero.
limit int 20 1–MAX_CHART_CATEGORIES (default 100).
sort str none none, asc, or desc.
colors list[str] palette Hex colors. Definition-only.
show_legend bool Type-dependent Defaults on for donut, pie, stacked, combo, radar, line, area.
width int 640 SVG width. Definition-only.
height int 240 SVG height. Definition-only.
fill bool false Fill a line chart; area is always filled. Definition-only.
zero bool true Include zero in line/area/combo scales. Definition-only.
comparison_label str field name Legend label for a comparison field. Definition-only.
comparison_color str faint Legend color for a comparison field. Definition-only.

Chart types:

line, area, bar, horizontal_bar, donut, pie, funnel, gauge, heatmap, radar, scatter, bubble, bullet, combo, stacked_bar, stacked_area (enezadashboard/widgets/chart.py:27-44).

Requirement matrix:

Type Category Value Series Line Size Measure/aggregation Target/scale
bar Yes Yes — — — — —
horizontal_bar Yes Yes — — — — —
line Yes Yes — — — — —
area Yes Yes — — — — —
donut Yes Yes — — — — —
pie Yes Yes — — — — —
funnel Yes Yes — — — — —
radar Yes Yes — — — — —
heatmap Yes Yes Yes — — — —
stacked_bar Yes Yes Yes — — — —
stacked_area Yes Yes Yes — — — —
scatter Yes (numeric) Yes — — — — —
bubble Yes (numeric) Yes — — Yes — —
bullet Yes Yes — — — — Optional
combo Yes Yes — Yes — — —
gauge — — — — — Yes Optional

Runtime rules:

  • Pie, donut, funnel, stacked bar, stacked area, and heatmap reject negative values with invalid_data (enezadashboard/widgets/chart.py:245-253).
  • Charts render server-side; no JavaScript chart library is loaded.
  • gauge uses a true aggregate, not report rows.

Table

Key Type Default Rules
columns list[str] First 6 report columns Each must be a report column/alias.
page_size int 20 1–MAX_PAGE_SIZE (default 100).
sortable bool true Enables sortable headers.
dense bool false Compact row rendering.
show_header bool true Show the table header.

Runtime query parameters: page, page_size, sort, dir. page_size is clamped to MAX_PAGE_SIZE (enezadashboard/widgets/table.py:45-111).

Report preview

Key Type Default Rules
columns list[str] First 6 report columns Each must be a report column/alias.
row_limit int 5 1–MAX_PREVIEW_ROWS (default 20).
show_header bool true Show the header.

A preview is a non-paginated table with page_size = row_limit. It reuses the table renderer, so sortable defaults to true internally, but the preview form does not expose a sortable toggle (enezadashboard/widgets/report_preview.py:30-43).


G. Layout and Widget Limits

Limit Value Source
Grid columns 12 enezadashboard/services/validation.py:44-49
x Non-negative; x + w <= 12 Same
y Non-negative; canvas endpoint caps at 200 enezadashboard/views/designer.py:645-654
w 2–12 Same
h 2–8 Same
Chart categories MAX_CHART_CATEGORIES (100) enezadashboard/widgets/chart.py:139-145
Table page size MAX_PAGE_SIZE (100) enezadashboard/widgets/table.py:23-29
Preview rows MAX_PREVIEW_ROWS (20) enezadashboard/widgets/report_preview.py:22-28
Dashboard data limit 1–1,000,000 (form) enezadashboard/forms.py:116-125

Default widget layout by type when a definition omits layout (enezadashboard/services/seeding.py:84-91):

Type Default x, y, w, h
kpi 0, 0, 3, 2
chart 0, 0, 6, 4
report_preview 0, 0, 6, 4
table 0, 0, 12, 4

H. Parameters, Filters, and Periods

Allowed widget parameters

parameter_config may contain only:

  • start_date, end_date for a DateRangeParam;
  • the parameter name and any form_fields for every other parameter.

Unknown keys fail validation with “Unknown report parameter(s)”.

Widget filter shape

json
{
  "condition": "AND",
  "primary_model": "frameworkapp.frameworktestdocumentline",
  "related_models": [],
  "groups": [
    {
      "condition": "AND",
      "rules": [
        {
          "id": "item_code",
          "field": "item_code",
          "type": "string",
          "input": "text",
          "operator": "equal",
          "value": "A-100"
        }
      ]
    }
  ]
}

Rules:

  • Each rule id must be in meta.filter_fields.
  • operator must be supported by the workflow engine.
  • Page-level user filters may use AND, OR, or NOT group conditions; NOT requires exactly one rule (enezadashboard/services/renderer.py:635-668).
  • Widget-level admin filters and page-level user filters merge with AND when the admin filter is also AND. An admin filter using OR is not merged, and the page shows a warning (enezadashboard/services/renderer.py:322-332, enezadashboard/services/renderer.py:733-758).

Dashboard and tab date settings

Key Location Meaning
date_range.enabled Tab filter_config Enables the tab's date defaults.
date_range.default_period Tab filter_config Preset or custom.
date_range.default_start_date Tab filter_config ISO date; used with custom.
date_range.default_end_date Tab filter_config ISO date; used with custom.
data.reference_date_field Tab filter_config Tab-level reference date override.
data.limit Tab filter_config Tab-level row cap.
parameter_defaults Tab filter_config Values applied to every widget before widget params.
data_settings.reference_date_field Dashboard Dashboard reference date.
data_settings.limit Dashboard Dashboard row cap.
data_settings.default_period Dashboard Dashboard default period.

Period resolution order:

  1. tab date_range.default_period (default means no range; a preset or custom resolves dates)
  2. tab date_range.default_start_date / default_end_date (when the period is custom)
  3. dashboard data_settings.default_period
  4. site DEFAULT_PERIOD

Reference-date resolution order:

  1. tab filter_config.data.reference_date_field
  2. dashboard data_settings.reference_date_field
  3. report's date_range.start_field
  4. report's date_field
  5. common created-date fields (created_at, created, …)
  6. the first date field on the model

Reference-date resolution is in enezadashboard/services/renderer.py:495-533. Period resolution is in enezadashboard/services/renderer.py:218-254.

Period presets

today, yesterday, last_7_days, last_30_days, this_week, last_week, this_month, last_month, this_quarter, last_quarter, this_year, last_year, ytd, custom (enezadashboard/services/periods.py:10-25).

Comparison choices: none, previous, previous_year (enezadashboard/services/periods.py:34-41).

Page query parameters

Parameter Meaning
period Preset key, custom, or default.
start_date, end_date Custom range, or legacy direct dates.
compare none, previous, previous_year.
filters JSON payload of page-level user filters, keyed by report.
page Table page number.
page_size Table page size.
sort, dir Table sort column and direction.
tab Selected tab code.

Invalid periods fall back to the configured default and add a warning rather than raising (enezadashboard/services/periods.py:218-260).


I. Settings

Settings are read by dashboard_settings() and merged over the defaults in enezadashboard/conf.py:3-21:

python
ENEZA_DASHBOARD_SETTINGS = {
    "DEFAULT_PAGE_SIZE": 20,
    "MAX_PAGE_SIZE": 100,
    "MAX_CHART_CATEGORIES": 100,
    "MAX_PREVIEW_ROWS": 20,
    "QUERY_CACHE_TTL": 0,
    "QUERY_TIMEOUT_MS": 0,
    "DESIGNER_ACTION_CODE": "action.enezadashboard.manage",
    "AUTO_REFRESH_MIN_SECONDS": 30,
    "DEFAULT_PERIOD": "last_30_days",
    "DEFAULT_COMPARE": "none",
    "MAX_USER_FILTER_RULES": 20,
    "MAX_USER_FILTER_GROUPS": 5,
}
Key Default Consumed by
DEFAULT_PAGE_SIZE 20 Table and renderer page size.
MAX_PAGE_SIZE 100 Table validation and renderer clamp.
MAX_CHART_CATEGORIES 100 Chart validation and rendering.
MAX_PREVIEW_ROWS 20 Report-preview validation.
DEFAULT_PERIOD last_30_days Renderer default period.
DEFAULT_COMPARE none Renderer default comparison.
MAX_USER_FILTER_RULES 20 Filter panel metadata.
MAX_USER_FILTER_GROUPS 5 Filter panel metadata.
QUERY_CACHE_TTL 0 Declared default; no cross-request TTL implementation exists.
QUERY_TIMEOUT_MS 0 Declared default; no query timeout is enforced.
DESIGNER_ACTION_CODE action code Declared default; designer enforcement currently hardcodes action.enezadashboard.manage.
AUTO_REFRESH_MIN_SECONDS 30 Declared default; no auto-refresh loop is implemented in the dashboard views.

The project already ships the main overrides in framework/settings.py:326-335. The remaining keys in the block above come from conf.py defaults. Override individual keys in the project's settings rather than redefining the whole dictionary.


J. Routes

All dashboard routes use the enezadashboard namespace.

Name Pattern
index /dashboards/
preference /dashboards/preferences/
manage_list /dashboards/manage/
create /dashboards/manage/create/
report_meta /dashboards/manage/report-meta/
designer /dashboards/manage/<uuid:dashboard_id>/
edit /dashboards/manage/<uuid:dashboard_id>/edit/
apply_wireframe /dashboards/manage/<uuid:dashboard_id>/apply-wireframe/
clone /dashboards/manage/<uuid:dashboard_id>/clone/
deactivate /dashboards/manage/<uuid:dashboard_id>/deactivate/
unpublish /dashboards/manage/<uuid:dashboard_id>/unpublish/
publish /dashboards/manage/<uuid:dashboard_id>/publish/
take_ownership /dashboards/manage/<uuid:dashboard_id>/take-ownership/
preview /dashboards/manage/<uuid:dashboard_id>/preview/
versions /dashboards/manage/<uuid:dashboard_id>/versions/
restore_version /dashboards/manage/<uuid:dashboard_id>/versions/<uuid:version_id>/restore/
tab_create /dashboards/manage/<uuid:dashboard_id>/tabs/
tab_update /dashboards/manage/<uuid:dashboard_id>/tabs/<uuid:tab_id>/
tab_delete /dashboards/manage/<uuid:dashboard_id>/tabs/<uuid:tab_id>/delete/
widget_create /dashboards/manage/<uuid:dashboard_id>/tabs/<uuid:tab_id>/widgets/
widget_update /dashboards/manage/<uuid:dashboard_id>/tabs/<uuid:tab_id>/widgets/<uuid:widget_id>/
widget_delete /dashboards/manage/<uuid:dashboard_id>/tabs/<uuid:tab_id>/widgets/<uuid:widget_id>/delete/
widget_preview /dashboards/manage/<uuid:dashboard_id>/tabs/<uuid:tab_id>/widgets/<uuid:widget_id>/preview/
widget_layout /dashboards/manage/<uuid:dashboard_id>/tabs/<uuid:tab_id>/widgets/<uuid:widget_id>/layout/
module_dashboards /dashboards/<str:module>/dashboards/
module_entry /dashboards/<str:module>/
detail /dashboards/<str:module>/<slug:dashboard_code>/
tab /dashboards/<str:module>/<slug:dashboard_code>/tabs/<slug:tab_code>/
widget /dashboards/<str:module>/<slug:dashboard_code>/tabs/<slug:tab_code>/widgets/<slug:widget_code>/

Source: enezadashboard/urls.py:7-129.


K. Error Codes

DashboardValidationError carries message, code, and optional structured errors (enezareporting/dashboard.py:30-47).

Code Raised when Typical fix
unknown_report A widget or definition references a code discovery does not know. Check report_ref, opt-in, import, and cache.
report_forbidden The user lacks the output permission or the report's access function. Grant output.<app_label>.<report_slug>.view; run rbac_sync.
report_not_eligible Execution was requested for an ineligible report. Fix opt-in, type, model, or columns.
invalid_config A widget field, type, format, limit, layout, measure, or aggregation is invalid. Read the error message; correct display_config.
invalid_parameters A parameter is unknown or fails the report form. Use allowed parameter names and valid values.
invalid_filter A filter field or operator is not allowed. Use meta.filter_fields and supported operators.
filters_not_supported A filter was supplied to a report without use_query_builder. Enable the report flag or remove the filter.
filters_unavailable The workflow filter engine is missing or filter metadata cannot be read. Install/configure the workflow engine.
invalid_date_field A dashboard reference date is not a date field on the report model. Choose a DateField/DateTimeField.
unsupported_aggregate A KPI aggregate was requested for a custom group-by report. Use a supported computation or numeric field.
invalid_data A chart type that cannot show negatives received one. Filter or choose another chart type.
query_failed An unexpected exception occurred while rendering a widget. Check the server log; the widget error is deliberately generic.
no_draft Publishing a dashboard with no draft version. Re-open the designer to create a draft.
publish_invalid Publication validation failed. Fix the listed tab/widget errors.
publish_forbidden The publisher cannot access the dashboard's module or access_code. Grant module/access-code permission or publish as a permitted user.
invalid_default Tried to default an unpublished or inactive dashboard. Publish and activate it first.
invalid_definition Seeding rejected a definition. Inspect the errors list from --dry-run --json.
default_conflict Another administrator-owned default exists for the module. Use --force deliberately or change ownership.
unknown_wireframe A definition or request names a wireframe that does not exist. Use a code from the catalogue.

Non-DashboardValidationError failures:

  • Duplicate report code — ImproperlyConfigured during discovery.
  • Duplicate definition identity — ValueError during load_definitions.
  • Model/slug validation — Django ValidationError from model or form validation.