This is a pre-release. djust 1.3.0 has shipped since.
Part of djust 1.3 — read the 1.3 release notes.
Before you upgrade, read the upgrade guide.
Fixed
- A model held in a container prints as its text when a filter prints the whole container.
{{ rows|pprint }}and{{ rows|json_script:"x" }}over a list, tuple, QuerySet or dict holding models now write each model'sstr(), as{{ rows }}does, instead of the model's serialized mapping.pprintwrites[Account:a1, Account:a2](Django writes therepr());json_scriptwrites["Account:a1", "Account:a2"]through the usual escaping (Django raisesTypeError). A named read ({{ r.name }}),{{ rows }},|length, an ordinary dict and the data itself (get_state(), the snapshot) are unchanged. To hand a model's fields to JavaScript, pass a plain dict of the fields you want (not the output ofnormalize_django_value, which carries a__str__text). Needs the rebuilt_rustmodule. - The JIT attribute gate applies the column-type floor like the serialization path does.
optimization/codegen.py::emittable_names, the gate behind the compiled serializers and the Rust serializers, decided by attribute name only, so a column the type floor drops (aBinaryField, a type named inLIVEVIEW_CONFIG['sensitive_field_types'], an encrypted-named type) was read by a template that named it. The gate now asksDjangoJSONEncoder._attr_is_readable, the name rules followed by the type floor, which neither an allowlist nor an opt-out lifts. The gate's cache key carries the model class and the configured types, and a full cache is cleared rather than frozen. The floor governs columns: a property, method, annotation orvalues_listrow carrying the same value is outside it, as on the eager path. Upgrade note: a JIT page that displayed an encrypted-named (or configured-sensitive, or binary) column now renders it empty; to show such a value deliberately, precompute a plain value inget_context_data()or a property, or remove the type fromLIVEVIEW_CONFIG['sensitive_field_types']/ rename the field class. 22 regression cases inpython/djust/tests/test_jit_gate_type_floor.py. - A model is not a mapping to a template. On a model held in LiveView state or in a container,
{{ r.items }},{{ r.values }}and{{ r.keys }}resolve to nothing (a bare{{ r.items }}prints nothing on most entries, and the textdict_items([])(dict_keys([]),dict_values([])) on LiveView for a list, QuerySet or top-level model and for QuerySet rows onDjustTemplateBackend, where Django prints nothing; no entry is ever printed),{% for k in r %},|unordered_list,|safeseqand|escapeseqrefuse the model as Django does (|joinreturns the model's text), and|stringformat:"(name)s",{% if 'name' in r %}/not in(both take theelsebranch) and|pluralizetreat it as the non-mapping Django does, instead of reading the map the model was serialized to. A named read ({{ r.name }}) is unchanged. The sinks go by the full identity shape a serializer stamps (__str__,__model__andpk), and a model whose__str__is aSafeStringis recognised like any other; a dict from user data that only carries a__str__key stays a dict (views, iteration,pprint,json_script), while{{ d }}and|lengthof it keep going by the__str__text as before. Needs the rebuilt_rustmodule.