mirror of https://github.com/django/django.git
Fixed #34532 -- Made formset_factory() respect Form's default_renderer.
Co-authored-by: David Smith <smithdc@gmail.com>
This commit is contained in:
parent
b9473cac65
commit
95e4d6b813
|
@ -99,6 +99,8 @@ class BaseFormSet(RenderableFormMixin):
|
||||||
self.error_class = error_class
|
self.error_class = error_class
|
||||||
self._errors = None
|
self._errors = None
|
||||||
self._non_form_errors = None
|
self._non_form_errors = None
|
||||||
|
self.form_renderer = self.renderer
|
||||||
|
self.renderer = self.renderer or get_default_renderer()
|
||||||
|
|
||||||
messages = {}
|
messages = {}
|
||||||
for cls in reversed(type(self).__mro__):
|
for cls in reversed(type(self).__mro__):
|
||||||
|
@ -224,7 +226,7 @@ class BaseFormSet(RenderableFormMixin):
|
||||||
# incorrect validation for extra, optional, and deleted
|
# incorrect validation for extra, optional, and deleted
|
||||||
# forms in the formset.
|
# forms in the formset.
|
||||||
"use_required_attribute": False,
|
"use_required_attribute": False,
|
||||||
"renderer": self.renderer,
|
"renderer": self.form_renderer,
|
||||||
}
|
}
|
||||||
if self.is_bound:
|
if self.is_bound:
|
||||||
defaults["data"] = self.data
|
defaults["data"] = self.data
|
||||||
|
@ -261,7 +263,7 @@ class BaseFormSet(RenderableFormMixin):
|
||||||
"prefix": self.add_prefix("__prefix__"),
|
"prefix": self.add_prefix("__prefix__"),
|
||||||
"empty_permitted": True,
|
"empty_permitted": True,
|
||||||
"use_required_attribute": False,
|
"use_required_attribute": False,
|
||||||
"renderer": self.renderer,
|
"renderer": self.form_renderer,
|
||||||
}
|
}
|
||||||
form = self.form(**form_kwargs)
|
form = self.form(**form_kwargs)
|
||||||
self.add_fields(form, None)
|
self.add_fields(form, None)
|
||||||
|
@ -566,7 +568,7 @@ def formset_factory(
|
||||||
"absolute_max": absolute_max,
|
"absolute_max": absolute_max,
|
||||||
"validate_min": validate_min,
|
"validate_min": validate_min,
|
||||||
"validate_max": validate_max,
|
"validate_max": validate_max,
|
||||||
"renderer": renderer or get_default_renderer(),
|
"renderer": renderer,
|
||||||
}
|
}
|
||||||
return type(form.__name__ + "FormSet", (formset,), attrs)
|
return type(form.__name__ + "FormSet", (formset,), attrs)
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,11 @@ from django.forms.formsets import (
|
||||||
all_valid,
|
all_valid,
|
||||||
formset_factory,
|
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.utils import ErrorList
|
||||||
from django.forms.widgets import HiddenInput
|
from django.forms.widgets import HiddenInput
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
|
@ -1553,6 +1557,60 @@ class FormsFormsetTestCase(SimpleTestCase):
|
||||||
self.assertEqual(formset.non_form_errors().renderer, renderer)
|
self.assertEqual(formset.non_form_errors().renderer, renderer)
|
||||||
self.assertEqual(formset.empty_form.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):
|
def test_repr(self):
|
||||||
valid_formset = self.make_choiceformset([("test", 1)])
|
valid_formset = self.make_choiceformset([("test", 1)])
|
||||||
valid_formset.full_clean()
|
valid_formset.full_clean()
|
||||||
|
|
|
@ -9,10 +9,12 @@ from django.db import models
|
||||||
from django.forms.formsets import formset_factory
|
from django.forms.formsets import formset_factory
|
||||||
from django.forms.models import (
|
from django.forms.models import (
|
||||||
BaseModelFormSet,
|
BaseModelFormSet,
|
||||||
|
ModelForm,
|
||||||
_get_foreign_key,
|
_get_foreign_key,
|
||||||
inlineformset_factory,
|
inlineformset_factory,
|
||||||
modelformset_factory,
|
modelformset_factory,
|
||||||
)
|
)
|
||||||
|
from django.forms.renderers import DjangoTemplates
|
||||||
from django.http import QueryDict
|
from django.http import QueryDict
|
||||||
from django.test import TestCase, skipUnlessDBFeature
|
from django.test import TestCase, skipUnlessDBFeature
|
||||||
|
|
||||||
|
@ -2365,3 +2367,44 @@ class TestModelFormsetOverridesTroughFormMeta(TestCase):
|
||||||
BookFormSet = modelformset_factory(Author, fields="__all__", renderer=renderer)
|
BookFormSet = modelformset_factory(Author, fields="__all__", renderer=renderer)
|
||||||
formset = BookFormSet()
|
formset = BookFormSet()
|
||||||
self.assertEqual(formset.renderer, renderer)
|
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)
|
||||||
|
|
Loading…
Reference in New Issue