#35191 closed New feature (wontfix)
Allow form renderer to use custom template for label tag
Reported by: | Oxan van Leeuwen | Owned by: | Almaz |
---|---|---|---|
Component: | Forms | Version: | 5.0 |
Severity: | Normal | Keywords: | forms render template |
Cc: | David Smith, Oxan van Leeuwen | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Currently, a form renderer can't easily change the template used by the BoundField.label_tag()
method: template_name_label
can be set on the form, but there exists no label_template_name
on the FormRenderer
that it fallbacks to.
This is problematic if e.g. CSS classes need to be set on the form labels. Writing out the <label>
tag in the template instead of calling label_tag()
is also not an option, as label_tag()
does somewhat complex processing to ensure the correct id (and label) are used.
Change History (5)
comment:1 by , 9 months ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:2 by , 9 months ago
Cc: | added |
---|---|
Easy pickings: | unset |
Resolution: | → wontfix |
Status: | assigned → closed |
Type: | Cleanup/optimization → New feature |
comment:3 by , 9 months ago
The problem with overriding the default template is that it's global to the project, while form renderers are local to the form. This is useful e.g. if multiple different form layouts are used within a project, or when incrementally transitioning between design systems. There's also the matter of consistency: the form, formset and field templates can already be changed by the renderer, why not the label? After all, the default template for those could also be globally overridden.
comment:4 by , 9 months ago
There's also the matter of consistency: the form, formset and field templates can already be changed by the renderer, why not the label?
There are also many templates that the renderer cannot override, such as ErrorDict
or ErrorList
templates. There are also many templates that the renderer cannot override, such as ErrorDict
or ErrorList
templates. Adding a new customization option is always a bit controversial (we already have many of them).
comment:5 by , 9 months ago
I agree there are more templates that the renderer can't override, but in practice those are less of a problem, as it's easy to just not use them in your form and field templates. For example ErrorDict
and ErrorList
are thin wrappers around dict
and list
respectively, and you can iterate over those directly in the field template to generate an error list in whatever style you want. That's not the case for the label template, as BoundField.label_tag()
contains (among other things) somewhat complex logic to generate the value for the for
attribute that can't easily be replicated in a template. Furthermore, even if you do replicate it, I'd be worried about that logic being considered an implementation detail and changing in a future version of Django.
What would also work is to extract the logic that generates the id and contents from label_tag()
out into separate methods (or properties) of BoundField
, which can then be used directly in the field template.
The wider context here (and also behind #35192) is that I'm trying to implement something that renders forms in a way that's usable with existing frontend frameworks (such as Bootstrap or Tailwind). Current attempts at this (such as django-crispy-forms or django-bootstrap5) all render using a custom template tag, whose implementation pokes around in the internals of the forms component. In my experience those always have hardcoded special casing and can't support the full feature set and extensibility of the forms component. It'd be great if something like that could be implemented in plain Django, working along with instead of around the forms component. Form renderers seem like the logical extension point for such an implementation, and they're nearly there, but at the moment they are a bit too inflexible to cleanly allow all necessary customization.
I don't think a new attribute is needed. You can always override the default template as any other template in your project.