summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Cave-Ayland <c.cave-ayland@imperial.ac.uk>2023-06-01 13:26:56 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2023-07-24 09:09:53 +0200
commit95e4d6b81312fdd9f8ebf3385be1c1331168b5cf (patch)
tree028600422e4c5f72fcce712aa5dd6a7f70118de3
parentb9473cac65190822e7c94f695f1f7b4d5b49502a (diff)
Fixed #34532 -- Made formset_factory() respect Form's default_renderer.
Co-authored-by: David Smith <smithdc@gmail.com>
-rw-r--r--django/forms/formsets.py8
-rw-r--r--tests/forms_tests/tests/test_formsets.py60
-rw-r--r--tests/model_formsets/tests.py43
3 files changed, 107 insertions, 4 deletions
diff --git a/django/forms/formsets.py b/django/forms/formsets.py
index fd4d53a44f..e279751601 100644
--- a/django/forms/formsets.py
+++ b/django/forms/formsets.py
@@ -99,6 +99,8 @@ class BaseFormSet(RenderableFormMixin):
self.error_class = error_class
self._errors = None
self._non_form_errors = None
+ self.form_renderer = self.renderer
+ self.renderer = self.renderer or get_default_renderer()
messages = {}
for cls in reversed(type(self).__mro__):
@@ -224,7 +226,7 @@ class BaseFormSet(RenderableFormMixin):
# incorrect validation for extra, optional, and deleted
# forms in the formset.
"use_required_attribute": False,
- "renderer": self.renderer,
+ "renderer": self.form_renderer,
}
if self.is_bound:
defaults["data"] = self.data
@@ -261,7 +263,7 @@ class BaseFormSet(RenderableFormMixin):
"prefix": self.add_prefix("__prefix__"),
"empty_permitted": True,
"use_required_attribute": False,
- "renderer": self.renderer,
+ "renderer": self.form_renderer,
}
form = self.form(**form_kwargs)
self.add_fields(form, None)
@@ -566,7 +568,7 @@ def formset_factory(
"absolute_max": absolute_max,
"validate_min": validate_min,
"validate_max": validate_max,
- "renderer": renderer or get_default_renderer(),
+ "renderer": renderer,
}
return type(form.__name__ + "FormSet", (formset,), attrs)
diff --git a/tests/forms_tests/tests/test_formsets.py b/tests/forms_tests/tests/test_formsets.py
index ee0ae5a426..3c260010c2 100644
--- a/tests/forms_tests/tests/test_formsets.py
+++ b/tests/forms_tests/tests/test_formsets.py
@@ -23,7 +23,11 @@ from django.forms.formsets import (
all_valid,
formset_factory,
)
-from django.forms.renderers import TemplatesSetting
+from django.forms.renderers import (
+ DjangoTemplates,
+ TemplatesSetting,
+ get_default_renderer,
+)
from django.forms.utils import ErrorList
from django.forms.widgets import HiddenInput
from django.test import SimpleTestCase
@@ -1553,6 +1557,60 @@ class FormsFormsetTestCase(SimpleTestCase):
self.assertEqual(formset.non_form_errors().renderer, renderer)
self.assertEqual(formset.empty_form.renderer, renderer)
+ def test_form_default_renderer(self):
+ """
+ In the absence of a renderer passed to the formset_factory(),
+ Form.default_renderer is respected.
+ """
+
+ class CustomRenderer(DjangoTemplates):
+ pass
+
+ class ChoiceWithDefaultRenderer(Choice):
+ default_renderer = CustomRenderer()
+
+ data = {
+ "choices-TOTAL_FORMS": "1",
+ "choices-INITIAL_FORMS": "0",
+ "choices-MIN_NUM_FORMS": "0",
+ }
+
+ ChoiceFormSet = formset_factory(ChoiceWithDefaultRenderer)
+ formset = ChoiceFormSet(data, prefix="choices")
+ self.assertEqual(
+ formset.forms[0].renderer, ChoiceWithDefaultRenderer.default_renderer
+ )
+ self.assertEqual(
+ formset.empty_form.renderer, ChoiceWithDefaultRenderer.default_renderer
+ )
+ default_renderer = get_default_renderer()
+ self.assertIsInstance(formset.renderer, type(default_renderer))
+
+ def test_form_default_renderer_class(self):
+ """
+ In the absence of a renderer passed to the formset_factory(),
+ Form.default_renderer is respected.
+ """
+
+ class CustomRenderer(DjangoTemplates):
+ pass
+
+ class ChoiceWithDefaultRenderer(Choice):
+ default_renderer = CustomRenderer
+
+ data = {
+ "choices-TOTAL_FORMS": "1",
+ "choices-INITIAL_FORMS": "0",
+ "choices-MIN_NUM_FORMS": "0",
+ }
+
+ ChoiceFormSet = formset_factory(ChoiceWithDefaultRenderer)
+ formset = ChoiceFormSet(data, prefix="choices")
+ self.assertIsInstance(formset.forms[0].renderer, CustomRenderer)
+ self.assertIsInstance(formset.empty_form.renderer, CustomRenderer)
+ default_renderer = get_default_renderer()
+ self.assertIsInstance(formset.renderer, type(default_renderer))
+
def test_repr(self):
valid_formset = self.make_choiceformset([("test", 1)])
valid_formset.full_clean()
diff --git a/tests/model_formsets/tests.py b/tests/model_formsets/tests.py
index 598dc57e7a..f78772da56 100644
--- a/tests/model_formsets/tests.py
+++ b/tests/model_formsets/tests.py
@@ -9,10 +9,12 @@ from django.db import models
from django.forms.formsets import formset_factory
from django.forms.models import (
BaseModelFormSet,
+ ModelForm,
_get_foreign_key,
inlineformset_factory,
modelformset_factory,
)
+from django.forms.renderers import DjangoTemplates
from django.http import QueryDict
from django.test import TestCase, skipUnlessDBFeature
@@ -2365,3 +2367,44 @@ class TestModelFormsetOverridesTroughFormMeta(TestCase):
BookFormSet = modelformset_factory(Author, fields="__all__", renderer=renderer)
formset = BookFormSet()
self.assertEqual(formset.renderer, renderer)
+
+ def test_modelformset_factory_default_renderer(self):
+ class CustomRenderer(DjangoTemplates):
+ pass
+
+ class ModelFormWithDefaultRenderer(ModelForm):
+ default_renderer = CustomRenderer()
+
+ BookFormSet = modelformset_factory(
+ Author, form=ModelFormWithDefaultRenderer, fields="__all__"
+ )
+ formset = BookFormSet()
+ self.assertEqual(
+ formset.forms[0].renderer, ModelFormWithDefaultRenderer.default_renderer
+ )
+ self.assertEqual(
+ formset.empty_form.renderer, ModelFormWithDefaultRenderer.default_renderer
+ )
+ self.assertIsInstance(formset.renderer, DjangoTemplates)
+
+ def test_inlineformset_factory_default_renderer(self):
+ class CustomRenderer(DjangoTemplates):
+ pass
+
+ class ModelFormWithDefaultRenderer(ModelForm):
+ default_renderer = CustomRenderer()
+
+ BookFormSet = inlineformset_factory(
+ Author,
+ Book,
+ form=ModelFormWithDefaultRenderer,
+ fields="__all__",
+ )
+ formset = BookFormSet()
+ self.assertEqual(
+ formset.forms[0].renderer, ModelFormWithDefaultRenderer.default_renderer
+ )
+ self.assertEqual(
+ formset.empty_form.renderer, ModelFormWithDefaultRenderer.default_renderer
+ )
+ self.assertIsInstance(formset.renderer, DjangoTemplates)