#35987 closed Bug (fixed)
ErrorList.copy() reverts to default renderer
Reported by: | Adam Johnson | Owned by: | Adam Johnson |
---|---|---|---|
Component: | Forms | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
When an ErrorList
is copied, it loses track of any custom renderer, reverting to the default one. Practically, this means custom styles are not applied to non-field errors when rendering a whole form.
For example, I wrote a custom renderer that swaps some templates like so:
from django import forms from django.forms.renderers import TemplatesSetting from django.template.exceptions import TemplateDoesNotExist class CustomRenderer(TemplatesSetting): def get_template(self, template_name): if template_name.startswith("django/forms/"): # Load our custom version from "custom/forms/" if it exists our_template = f"custom/{template_name.removeprefix('django/')}" try: return super().get_template(our_template) except TemplateDoesNotExist: pass return super().get_template(template_name) class MyForm(forms.Form): default_renderer = CustomRenderer()
The custom error list template uses some CSS utility classes from Tailwind, like text-red-600
:
{% if errors %}<ul class="text-red-600">{% for error in errors %}<li>{{ error }}</li>{% endfor %}</ul>{% endif %}
Creating a form with a non-field error and rendering those errors uses the custom template:
In [1]: from example.forms import MyForm ...: ...: form = MyForm({}) ...: form.full_clean() ...: form.add_error(None, "Test error") In [2]: form.non_field_errors().render() Out[2]: '<ul class="text-red-600"><li>Test error</li></ul>'
But rendering the whole form reverts to the default template, from the default renderer:
In [3]: form.render() Out[3]: '<ul class="errorlist nonfield"><li>Test error</li></ul>\n\n <div></div>'
This occurs because the ErrorList
is copied in Form.get_context()
:
The fix would be to also copy over renderer
in ErrorList.copy()
:
I think this has probably been an issue ever since a custom renderer became possible in #31026.
Change History (5)
comment:1 by , 9 days ago
Has patch: | set |
---|
comment:2 by , 9 days ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:3 by , 9 days ago
Triage Stage: | Accepted → Ready for checkin |
---|
Thank you!