djust docs
Browse documentation
reference

djust 1.1.4 release notes

A security maintenance release for the 1.1 line, released 2026-09-23 alongside 1.2.0. It fixes eleven advisories and tightens several defaults; read the behaviour changes before upgrading.

On this page

September 23, 2026

djust 1.1.4 is a security maintenance release for the 1.1 line. It was released on the same day as djust 1.2 and carries the same security fixes, without 1.2's new features or its template-engine changes.

Every project on 1.1.x should upgrade. Several of the fixes close a hole by changing a default, so read Backwards incompatible changes in 1.1.4 before you deploy. If you are ready to move to the 1.2 line, the 1.2 release notes describe the full upgrade, and 1.2.0 includes every fix listed here.

Python and Django support are unchanged from 1.1: Python 3.10 to 3.14 and Django 4.2 to 5.2.

Security

1.1.4 includes fixes for the following advisories. Each advisory has the details, the affected versions and the credit.

AdvisoryArea
GHSA-fccp-5h88-g34jDataTable sorting, filtering and grouping
GHSA-jv2m-fcq9-94xfdjust admin (admin_ext) permissions
GHSA-c44q-w252-mr67Observability endpoints
GHSA-hc2m-gvfj-x6r3Built-in components
GHSA-r372-rrpw-5cgjBuilt-in components
GHSA-j23m-jxwp-m3vqTheming
GHSA-6q7c-hvpc-ff2qPresence and channel groups
GHSA-5ffg-p52h-v2phBack-navigation state snapshots
GHSA-74vj-mpp4-45cgSticky {% live_render %} children
GHSA-7fcf-23mf-rhhmResumable uploads
GHSA-p9vp-rh5f-2cvqCustom template filters (fixed on the 1.2 line in 1.2.0rc2)

Backwards incompatible changes in 1.1.4

Each of these closes one of the advisories above. They are the same changes 1.2.0 makes, and the 1.2 notes explain each one in more detail.

  • djust admin enforces model permissions. DjustModelAdmin checks has_view_permission, has_add_permission, has_change_permission and has_delete_permission on every page, save and delete, and the defaults now call user.has_perm() with the model's view_ / add_ / change_ / delete_ permission, as Django's ModelAdmin does. Staff users who aren't superusers need those permissions; before, any active staff account had full access.
  • Built-in components HTML-escape the values they render. HTML passed to a content slot (a modal, card or tab body, a header, a footer, an icon) must be marked safe with mark_safe(), or it is shown as text. Link and image URLs with a javascript:, vbscript: or non-image data: scheme render as #. The rich-text editor's value is cleaned to an HTML allowlist instead of escaped.
  • Custom template filters registered with is_safe=True keep their output escaped unless their input was already safe, as in Django. A filter that produces markup must return mark_safe(...) or format_html(...) itself.
  • The observability endpoints need a token. Requests must come straight from a loopback client with no proxy headers and must send the X-Djust-Observability-Token header. manage.py djust_mcp sends it for you; print it for other tools with manage.py djust_observability_token.
  • DataTable sorts, filters and groups only on declared columns. A column is sortable unless it sets "sortable": False, and filterable only when it sets "filterable": True. Unknown column names are ignored.
  • Back-navigation state snapshots from earlier versions are rejected once and the view mounts fresh.
  • Resumable uploads started before the upgrade restart from the beginning, and resume only in the session that started them.
  • Theme cookies naming an unregistered pack or an invalid layout fall back to the defaults.

Bug fixes

  • A LiveView joins its channel groups (view, presence, db_notify) only after its permission checks and on_mount hooks pass. A refused mount leaves every group, and presence and push messages no longer reach a connection with no mounted view.
  • A reused sticky {% live_render %} child re-runs its view and object permission checks on every parent render, and live_redirect carry-over re-checks object permissions.
  • {% theme_css_link %} URL-encodes its query string.
  • AzureBlockBlobWriter raises RuntimeError when it is used before it is opened, instead of passing an unset blob name to the Azure client.

The full entry is in the [1.1.4] section of the 1.1 branch's CHANGELOG.

Upgrading

pip install "djust==1.1.4"
python manage.py collectstatic --noinput
python manage.py check

Then work through the list above: grant model permissions to staff who use djust admin, mark component slot HTML safe, add "filterable": True to DataTable columns you filter on, and give any observability client the token.