[Django] #37262: Form media given as html-safe strings rendered as paths on 6.1

2 views
Skip to first unread message

Django

unread,
Aug 8, 2026, 6:18:45 PM (2 days ago) Aug 8
to django-...@googlegroups.com
#37262: Form media given as html-safe strings rendered as paths on 6.1
----------------------------------------+------------------------------
Reporter: Adam Johnson | Owner: Adam Johnson
Type: Bug | Status: assigned
Component: Forms | Version: 6.1
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 1
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
----------------------------------------+------------------------------
Since #29490 (Django 4.1), `Media` assets may be given as hashable objects
implementing `__html__()`, rendered verbatim as the complete tag, per the
old
[https://docs.djangoproject.com/en/5.1/topics/forms/media/#paths-as-
objects "Paths as objects" docs section].
Html-safe strings from `mark_safe()` satisfy that contract, but since
8096b5251090bf7539c59956e398b027c7525529 (#37085) they are treated as
static
file paths instead: `Media.__init__()` now normalizes every
`isinstance(path, str)` entry into `Script`/`Stylesheet`, and `SafeString`
is
a `str` subclass, so e.g.
`forms.Media(js=[mark_safe('<script defer
src="https://example.org/asset.js"></script>')])`
renders as
`<script
src="/static/%3Cscript%20defer%20src%3D%22https%3A/..."></script>`
rather than the tag verbatim as in 6.0. The same happens for `css` entries
but
non-str `@html_safe` classes still work.

The fix is to skip normalization for any string that provides
`__html__()`, so that they take the pre-existing verbatim rendering
branch.
--
Ticket URL: <https://code.djangoproject.com/ticket/37262>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Aug 8, 2026, 6:29:00 PM (2 days ago) Aug 8
to django-...@googlegroups.com
#37262: Form media given as html-safe strings rendered as paths on 6.1
------------------------------+----------------------------------------
Reporter: Adam Johnson | Owner: Adam Johnson
Type: Bug | Status: assigned
Component: Forms | Version: 6.1
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
------------------------------+----------------------------------------
Description changed by Adam Johnson:

Old description:

> Since #29490 (Django 4.1), `Media` assets may be given as hashable
> objects
> implementing `__html__()`, rendered verbatim as the complete tag, per the
> old
> [https://docs.djangoproject.com/en/5.1/topics/forms/media/#paths-as-
> objects "Paths as objects" docs section].
> Html-safe strings from `mark_safe()` satisfy that contract, but since
> 8096b5251090bf7539c59956e398b027c7525529 (#37085) they are treated as
> static
> file paths instead: `Media.__init__()` now normalizes every
> `isinstance(path, str)` entry into `Script`/`Stylesheet`, and
> `SafeString` is
> a `str` subclass, so e.g.
> `forms.Media(js=[mark_safe('<script defer
> src="https://example.org/asset.js"></script>')])`
> renders as
> `<script
> src="/static/%3Cscript%20defer%20src%3D%22https%3A/..."></script>`
> rather than the tag verbatim as in 6.0. The same happens for `css`
> entries but
> non-str `@html_safe` classes still work.
>
> The fix is to skip normalization for any string that provides
> `__html__()`, so that they take the pre-existing verbatim rendering
> branch.

New description:

Since #29490 (Django 4.1), `Media` assets may be given as hashable objects
implementing `__html__()`, rendered verbatim as the complete tag, per the
old [https://docs.djangoproject.com/en/5.1/topics/forms/media/#paths-as-
objects "Paths as objects" docs section].
Html-safe strings from `mark_safe()` satisfy that contract, but since
8096b5251090bf7539c59956e398b027c7525529 (#37085) they are treated as
static file paths instead: `Media.__init__()` now normalizes every
`isinstance(path, str)` entry into `Script`/`Stylesheet`, and `SafeString`
is a `str` subclass, so e.g. `forms.Media(js=[mark_safe('<script defer
src="https://example.org/asset.js"></script>')])`
renders as`<script
src="/static/%3Cscript%20defer%20src%3D%22https%3A/..."></script>` rather
than the tag verbatim as in 6.0. The same happens for `css` entries but
non-str `@html_safe` classes still work.

The fix is to skip normalization for any string that provides
`__html__()`, so that they take the pre-existing verbatim rendering
branch.

--
--
Ticket URL: <https://code.djangoproject.com/ticket/37262#comment:1>

Django

unread,
6:31 AM (2 hours ago) 6:31 AM
to django-...@googlegroups.com
#37262: Form media given as html-safe strings rendered as paths on 6.1
------------------------------+----------------------------------------
Reporter: Adam Johnson | Owner: Adam Johnson
Type: Bug | Status: assigned
Component: Forms | Version: 6.1
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
------------------------------+----------------------------------------
Changes (by David Smith):

* stage: Unreviewed => Accepted

Comment:

#37268 was also opened which seems to be a duplicate of this issue.
--
Ticket URL: <https://code.djangoproject.com/ticket/37262#comment:2>
Reply all
Reply to author
Forward
0 new messages