Skip to content

Settings

dj-layouts is configured via a single DJ_LAYOUTS dict in your Django settings.py. All keys are optional; sensible defaults apply.

# settings.py
DJ_LAYOUTS = {
    "DEBUG_ERRORS": None,
    "CACHE_ENABLED": True,
    "CACHE_BACKEND": "default",
    "PARTIAL_DETECTORS": [],
    "DETECTOR_RAISE_EXCEPTIONS": False,
    "HTMX_SMART_ROUTING": False,
    "HTMX_CONTENT_TARGET": "#panel-content",
    "HTMX_COOKIE_NAME": "dj_layout_current",
    "HTMX_COOKIE_DOMAIN": None,
}

DEBUG_ERRORS

Type: bool | None Default: None

Controls whether panel rendering errors raise a PanelRenderError exception (showing Django's debug error page) or are handled gracefully by on_panel_error().

Value Behaviour
None (default) Follows Django's DEBUG setting
True Always raise PanelRenderError (debug mode, regardless of DEBUG)
False Always call on_panel_error() (production mode, even when DEBUG = True)

Debug mode behaviour

When DEBUG_ERRORS resolves to True:

  • on_panel_error() is not called
  • A PanelRenderError exception is raised immediately
  • Django's standard error page appears with the full traceback

This makes it easy to spot panel failures during development — you get the real exception, not a silently swallowed error.

Production mode behaviour

When DEBUG_ERRORS resolves to False:

  • The exception is logged automatically at ERROR level
  • on_panel_error() is called with a PanelError dataclass
  • The return value of on_panel_error() is used as the panel's HTML
  • The page renders with an error fallback in the failed panel's slot

Examples

# settings.py

DJ_LAYOUTS = {
    # Default — follows DEBUG (omit the key or set to None):
    # "DEBUG_ERRORS": None,

    # Force debug behaviour in staging (DEBUG might be False):
    "DEBUG_ERRORS": True,

    # Force production behaviour locally to test error handling:
    "DEBUG_ERRORS": False,
}

Relationship with DEBUG

DEBUG_ERRORS = None   and   DEBUG = True   →  debug mode  (raises PanelRenderError)
DEBUG_ERRORS = None   and   DEBUG = False  →  production  (calls on_panel_error)
DEBUG_ERRORS = True   (any DEBUG)          →  debug mode  (raises PanelRenderError)
DEBUG_ERRORS = False  (any DEBUG)          →  production  (calls on_panel_error)

See Error Handling for details on on_panel_error(), PanelError, and PanelRenderError.


CACHE_ENABLED

Type: bool Default: True

When set to False, all panel caching is disabled globally — panels always re-render even when a cache= argument is provided in their Panel(...) definition.

This is useful in development or testing where you want predictable, uncached behaviour:

# settings/local.py
DJ_LAYOUTS = {
    "CACHE_ENABLED": False,
}

Note that this setting does not affect Django's own cache framework — it only controls whether dj-layouts writes to or reads from the cache for panel results.


CACHE_BACKEND

Type: str Default: "default"

The name of the Django cache backend used as the default for panel caching when no backend= is specified on the CacheConfig. Must be a key in settings.CACHES.

CACHES = {
    "default": {"BACKEND": "django.core.cache.backends.locmem.LocMemCache"},
    "panels":  {"BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache", ...},
}

DJ_LAYOUTS = {
    "CACHE_BACKEND": "panels",
}

Individual panels can always override the backend per-panel:

Panel("myapp:nav", cache=cache.sitewide(timeout=3600, backend="panels"))

PARTIAL_DETECTORS

Type: list[str] Default: []

A list of dotted import paths to partial detector callables. Each detector receives the current request and returns True if the request should skip layout assembly and return only the partial view response.

DJ_LAYOUTS = {
    "PARTIAL_DETECTORS": [
        "dj_layouts.detection.htmx_detector",
        "dj_layouts.detection.query_param_detector",
    ],
}

Built-in detectors:

  • dj_layouts.detection.never_detector — always False (layout always assembled)
  • dj_layouts.detection.htmx_detectorTrue when HX-Request: true header is present
  • dj_layouts.detection.query_param_detectorTrue when ?_partial=1 is in the query string

Detectors are loaded lazily on first request. An invalid path raises ImproperlyConfigured.

See Partial Detection for the full reference.


DETECTOR_RAISE_EXCEPTIONS

Type: bool Default: False

When False (default), exceptions raised inside a detector are logged at WARNING level and the detector is treated as returning False. Layout assembly proceeds normally.

When True, detector exceptions propagate as-is. Useful in development to catch broken detectors immediately.

# settings/local.py
DJ_LAYOUTS = {
    "DETECTOR_RAISE_EXCEPTIONS": True,
}

HTMX_SMART_ROUTING

Type: bool Default: False

Enables Out-of-the-Box Single Page Application (SPA) routing transitions using HTMX. When enabled, dj-layouts uses a cookie to track the user's current layout, dynamically deciding when to return lightweight partials (when navigating within the same layout) and when to return a fully assembled layout (when transitioning between different layouts).

DJ_LAYOUTS = {
    "HTMX_SMART_ROUTING": True,
}

HTMX_CONTENT_TARGET

Type: str Default: "#panel-content"

The CSS selector of the main content container where the partial view's content should be injected when navigating within the same layout.

DJ_LAYOUTS = {
    "HTMX_CONTENT_TARGET": "#main-container",
}

Type: str Default: "dj_layout_current"

The name of the cookie used to track which Layout class is currently loaded in the user's browser.

DJ_LAYOUTS = {
    "HTMX_COOKIE_NAME": "my_layout_tracker",
}

Type: str | None Default: None

The domain to set on the layout tracking cookie. Set to e.g., ".domain.com" if your application operates across multiple subdomains and you need them to share the layout status to prevent full page reloads.

DJ_LAYOUTS = {
    "HTMX_COOKIE_DOMAIN": ".app.com",
}