#35987: ErrorList.copy() reverts to default renderer
----------------------------------------+------------------------------
Reporter: Adam Johnson | Owner: Adam Johnson
Type: Bug | Status: assigned
Component: Forms | Version: dev
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
----------------------------------------+------------------------------
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:
{{{#!python
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`:
{{{#!htmldjango
{% 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:
{{{#!pycon
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:
{{{#!pycon
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()`:
https://github.com/django/django/blob/1860a1afc9ac20750f932e8e0a94b32d096f2848/django/forms/forms.py#L225
The fix would be to also copy over `renderer` in `ErrorList.copy()`:
https://github.com/django/django/blob/1860a1afc9ac20750f932e8e0a94b32d096f2848/django/forms/utils.py#L165
I think this has probably been an issue ever since a custom renderer
became possible in #31026.
--
Ticket URL: <https://code.djangoproject.com/ticket/35987>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/django-updates/01070193aafd7bcc-ad9e7bbd-7d87-4a3b-94fb-e2c3a6fd47a1-000000%40eu-central-1.amazonses.com.