fix: #5486 give MultiWidget fields a working label association - #5487
Merged
mauromsl merged 1 commit intoSep 3, 2026
Merged
Conversation
…tion
`BoundField.id_for_label` is the empty string for any MultiWidget, so
`admin/elements/forms/field.html` emitted `<label for="">` — associated with
nothing. Every field rendered through this partial with a MultiWidget-based
widget therefore had no accessible name.
It is not cosmetic on the registration form: with the default
`CAPTCHA_TYPE = "simple_math"`, django-simple-math-captcha's MathCaptchaField
is a MultiWidget, so the required captcha input is announced as nothing and a
screen-reader user cannot complete registration.
Falls back to the first subwidget, which Django ids as `<auto_id>_0`. Fields
that already have an `id_for_label` take the existing branch and render
byte-identically, so the ~20 templates including this partial are unaffected.
Verified by rendering the patched line against both field types:
email -> for="id_email" (unchanged)
captcha -> for="id_captcha_0" (was for="")
mauromsl
approved these changes
Sep 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
closes #5486
The bug
templates/admin/elements/forms/field.htmlrenders<label for="{{ field.id_for_label }}">. Django returns the empty string fromBoundField.id_for_labelwhenever the widget is aMultiWidget, because there is no single control to point at — so the partial emits<label for="">, associated with nothing, and the field has no accessible name.Not cosmetic on the registration form: with the default
CAPTCHA_TYPE = "simple_math",django-simple-math-captcha'sMathCaptchaFieldis a MultiWidget, so the required captcha input is announced as nothing. A screen-reader user cannot complete registration.The partial is included from ~20 templates, so any other MultiWidget field (
SplitDateTimeWidget, etc.) is affected wherever it renders.The change
One line: fall back to the first subwidget, which Django ids as
<auto_id>_0.Why it is safe for the other ~20 include sites
Any field that already has an
id_for_labeltakes the existing branch, so its output is byte-identical. Verified by rendering the patched line against both a plain field and a MultiWidget:The reproduction in #5486 is standalone — plain Django, no Janeway needed — if you want to confirm before and after yourself.
Deliberately not included
For the captcha specifically the question (
<span class="captcha-question">) sits outside the label, so even with a correctforthe accessible name is just "Answer this question:" — the user is told to answer a question they are never read. Fixing that by wrapping{{ field }}in the label would be wrong here, because a MultiWidget that renders several real inputs (e.g.SplitDateTimeWidget) would end up with two controls under one label. It likely belongs in the captcha field's own rendering rather than this shared partial. Happy to follow up separately if you'd like it addressed.