Standardized App Structure

Developer guide for the Enezaframework. Part of the architecture series.

Table of Contents

  1. Why a Standard Structure
  2. Directory Layout
  3. The models/ Package
  4. The views/ Package
  5. Templates
  6. Migrations
  7. Requirements Docs
  8. Related Guides

Why a Standard Structure

Every business-logic app follows the same layout so that tooling, the CLI, and human developers can predict where things live. Enezaframework reads models and views through package __init__ re-exports, so following the import conventions is not optional — it is what makes from accountpayable.models import * work.


Directory Layout

eneza startapp creates this scaffold with empty models/, views/ and migrations/ packages. Each package contains only __init__.py; no sample model, sample view or sample menu item is generated. Add model and view files as the app grows, then re-export them from the package __init__.py.

A typical app looks like this:

text
accountpayable/
├── __init__.py
├── admin.py
├── apps.py                 # App config + navigation menus
├── models/                 # One file per model
│   ├── __init__.py         # Re-exports every model
│   ├── vendortable.py
│   └── vendortabledetails.py
├── views/                  # One file per view group
│   ├── __init__.py         # Re-exports every view
│   └── vendorviews.py
├── templates/              # Only when generic templates are insufficient
│   └── accountpayable/
├── requirements/           # PRD.md and other specifications
├── urls.py                 # Aggregates auto-registered URLs
└── migrations/
    └── __init__.py
flowchart TD
    APP[accountpayable app]
    APP --> APPSPY[apps.py<br/>config + menus]
    APP --> MODELS[models package]
    APP --> VIEWS[views package]
    APP --> URLS[urls.py]
    APP --> MIG[migrations]
    APP --> TMPL[templates optional]
    APP --> REQ[requirements docs]

    MODELS --> M1[vendortable.py]
    MODELS --> M2[vendortabledetails.py]
    MODELS --> MINIT[__init__.py re-exports]

    VIEWS --> V1[vendorviews.py]
    VIEWS --> VINIT[__init__.py re-exports]

The generated apps.py starts with menus = [] and an app_entry_menu that resolves to the dashboard module entry. The app appears in the module menu, but its fast tabs stay empty until views and menu items are added.


The models/ Package

  • Put each model in its own file, for example models/customertable.py and models/vendortable.py.
  • models/__init__.py must import every model from its file so callers can do a single import.
python
# accountpayable/models/__init__.py
from .vendortable import VendorTable
from .vendortabledetails import VendorTableDetails
from .vendorpostinggroup import VendorPostingGroup
from .vendorgroup import VendorGroup

With that in place, other modules can import cleanly:

python
from accountpayable.models import VendorTable, VendorTableDetails

The framework itself follows the same pattern. See enezaframework/models/__init__.py for the canonical example. Because of that file, from enezaframework.models import EnezaMaster, EnezaDocument works, while a class that is not re-exported there is not importable from the package root.

Models should inherit from an Enezaframework base model rather than models.Model directly whenever they participate in the standard CRUD/multi-tenant behavior. See Base Models & Model Types.


The views/ Package

  • Put a view or a closely related set of views in its own file, for example views/customerviews.py and views/vendorviews.py.
  • views/__init__.py must import those views so URL generation and cross-imports resolve.
python
# accountpayable/views/__init__.py
from .vendorviews import *

Then the app's urls.py can do from . import views and reference views.cashandbankdashboard for manually defined views.

Each framework view should be decorated with @auto_url_register; see URL Auto-Registration.


Templates

Most apps do not need their own templates. Enezaframework ships generic list, detail, and form templates that the base views reuse.

  • Only create a custom template when there is a presentation requirement the generic templates cannot satisfy.
  • App-specific templates live under a subdirectory named after the app, for example templates/accountpayable/.
  • Reuse the base HTML design and static assets described in Frontend Templates & UI Reuse.

Migrations

Standard Django migrations manage schema changes for the app's models.

bash
python manage.py makemigrations accountpayable
python manage.py migrate

Keep the standard migrations/__init__.py in place.


Requirements Docs

The requirements/ folder holds the app's Product Requirement Documents (PRD.md) and other specifications. Use it to document why the app exists, its entities, and its business rules, so future work has a written reference.