﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
35987	ErrorList.copy() reverts to default renderer	Adam Johnson	Adam Johnson	"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."	Bug	closed	Forms	dev	Normal	fixed			Ready for checkin	1	0	0	0	0	0
