Inline & Specialized Views

Developer guide for the Enezaframework. Part of the Developer documentation.

Table of Contents

  1. Overview
  2. Inline Views
  3. BaseInlineOneToOneDetailView
  4. Journals Views
  5. Setup Views
  6. Source Document Views
  7. Image Views
  8. Change History
  9. Related Guides

Overview

Beyond the core CRUD views, Enezaframework provides two families of views:

  • Inline views manage records that belong to a parent record (one-to-many or one-to-one) and are rendered inside the parent's detail page.
  • Specialized views behave like the core views but are tailored to a class of models (journals, setups, source documents, images).
classDiagram
    class BaseDetailView
    class BaseListView
    class BaseCreateView
    class BaseDeleteView
    class BaseInlineListView
    class BaseInlineDetailView
    class BaseInlineCreateView
    class BaseInlineDeleteView
    class BaseInlineOneToOneDetailView
    class BasejournalsListView
    class BaseSetupsListview
    class BaseSourceDocumentListView
    class BaseImagesListview

    BaseInlineListView --|> BaseListView
    BaseInlineDetailView --|> BaseDetailView
    BaseInlineCreateView --|> BaseCreateView
    BaseInlineDeleteView --|> BaseDeleteView
    BaseInlineOneToOneDetailView --|> BaseInlineDetailView
    BasejournalsListView --|> BaseListView
    BaseSetupsListview --|> BaseListView
    BaseSourceDocumentListView --|> BaseListView
    BaseImagesListview --|> BaseInlineListView

Inline Views

View Purpose
BaseInlineListView Lists child records for a parent.
BaseInlineDetailView Shows/edits one child record.
BaseInlineCreateView Creates a child record under a parent.
BaseInlineDeleteView Deletes a child record.
BaseInlineOneToOneDetailView Shows/edits a strictly one-to-one related object.

Inline views are usually invoked by the parent detail view using HTMX, which swaps their content into an inline tab. The parent declares them in get_inline_related_objects; see Field & Inline UI Configuration.


BaseInlineOneToOneDetailView

Specialized for a related object in a strict one-to-one relationship with the parent.

Required attributes:

Attribute Description
model The inline model class.
parent_model The parent model class.
related_name The related_name on the FK/O2O from the inline model back to the parent.
detail_ui_view Form layout (same schema as core detail views).
python
from enezaframework.views import BaseInlineOneToOneDetailView
from enezaframework.utils import auto_url_register
from accountpayable.models import VendorTable, VendorTableDetails


@auto_url_register
class VendorTableDetailsInlineView(BaseInlineOneToOneDetailView):
    model = VendorTableDetails
    parent_model = VendorTable
    related_name = "details"

    def detail_ui_view(self):
        return [
            {
                "name": "Purchase demographics",
                "icon": "Home",
                "Fieldcolumns": [
                    {"fields": ["segment"]},
                ],
            },
        ]

For conditional or generic one-to-one inlines, the parent view supplies get_related_object_id to resolve the object being edited. Match the related_name used here with the relation_name declared in the parent's get_inline_related_objects.

When both the inline model and the parent_model expose a party ForeignKey, the view acts as a "party bridge": it resolves the related object through parent.party and sets form.instance.party on save, so you do not manage the FK by hand.


Journals Views

For models that inherit from a journal header/line base (for example JournalBatch and its lines).

View Purpose
BasejournalsListView Lists journal headers.
BasejournalsDetailView Shows a journal header with lines.
BasejournalsCreateView Creates a journal header.
BasejournalsDeleteView Deletes a journal header.
BaseJournalsLinesListView Lists journal lines.
BaseJournalsLinesDetailView Shows/edits a journal line.
BaseJournalsLinesCreateView Creates a journal line.
BaseJournalsLinesDeleteView Deletes a journal line.

Line views are typically used as inlines under BasejournalsDetailView. The detail views define action_list = [] and load inlines through get_inline_related_objects, so override those the same way you would on a core detail view.

Note the exact spelling: the header classes use a lowercase j (BasejournalsListView), while the line classes use BaseJournalsLines.... Import the names you actually need from enezaframework.views.


Setup Views

For models that inherit from EnezaSetup (see Base Models & Model Types).

View Purpose
BaseSetupsListview Lists setup records.
BaseSetupsDetailView Shows/edits a setup record.
BaseSetupsCreateView Creates a setup record.
BaseSetupsDeleteView Deletes a setup record.

Read-only variants

View Purpose
BaseSetupsReadOnlyListView Lists setup records without edit affordances.
BaseSetupsReadOnlyDetailView Shows setup records without allowing modification.
BaseSetupsReadOnlyCreateView Create-with-locked-fields variant.

Use the read-only variants when setup data must be visible but not editable in a given context or for a given role. BaseSetupsDetailView, BaseSetupsCreateView, and BaseSetupsDeleteView also ship setup- specific templates under setups/.

python
from enezaframework.views import BaseSetupsListview
from enezaframework.utils import auto_url_register
from accountpayable.models import VendorPostingGroup


@auto_url_register
class VendorPostingGroupListView(BaseSetupsListview):
    model = VendorPostingGroup

    def set_list_fields(self):
        return ["code", "description"]

    def set_search_fields(self):
        return ["code", "description"]

The class name is BaseSetupsListview (lowercase v). Import it from enezaframework.views.


Source Document Views

For "source document" models (sales orders, purchase invoices, and similar) that need a header/lines layout.

View Purpose
BaseSourceDocumentListView Lists source documents.
BaseSourceDocumentDetailView Shows a document with header and lines.
BaseSourceDocumentCreateView Creates a source document.
BaseSourceDocumentDeleteView Deletes a source document.

These views support the headerpostion tab key ("header" or "lines") so a tab's content renders in the document header region or alongside the lines.

python
def detail_ui_view(self):
    return [
        {
            "name": "General",
            "icon": "Home",
            "headerpostion": "header",
            "Fieldcolumns": [
                {"fields": ["document_no", "customer"]},
            ],
        },
        {
            "name": "Lines",
            "icon": "Home",
            "headerpostion": "lines",
            "Fieldcolumns": [
                {"fields": ["total_amount", "currency"]},
            ],
        },
    ]

Image Views

For managing image records attached to a parent, the framework ships inline image views.

View Purpose
BaseImagesListview Lists images (inline).
BaseImagesDetailView Shows/edits an image (inline).
BaseImagesCreateView Creates an image (inline).
BaseImagesDeleteView Deletes an image (inline).

These pair with ConfigurableImageField / ConfigurableMultipleImageField; see Model Field Conventions.


Change History

Dated changes that affect this guide, taken from docs/Release note/CHANGELOG.md and the release notes. For the complete history, see the changelog.

Date Version What changed
2026-06-27 — Nested inline children support added; new inline_details_partial.html and inline_update_partial.html partials.
2026-06-30 0.2.8 Rich text, button group, and label widgets applied across inline forms.
2026-07-02 0.2.12 Inline column width and field full_width fixed across 7 inline templates.
2026-07-05 0.2.13 Inline tab_group placement added; inline accordion toggle fixed.
2026-07-06 0.2.14 Inline list pages reload correctly after save via htmx.process(targetElement).
2026-07-10 0.2.16 Optional url_name added for non-UrlMixin views, including BaseInlineDeleteView.
2026-07-11 0.2.17 Inline tab URLs now honour a custom url_name (get_inline_fieldtab_config()).
2026-07-17 0.2.18 Setup/inline templates call initTomSelects() so M2M widgets render correctly.
2026-08-23 0.2.19 TomSelect auto-initializes on load and after every HTMX swap.