From 21ceaf2fd75bb994b7a0e3b691171d6b34ffc913 Mon Sep 17 00:00:00 2001 From: Rudraksha Dwivedi <146867502+Rudraksha-007@users.noreply.github.com> Date: Tue, 13 Jan 2026 00:04:14 +0530 Subject: [PATCH] Fixed #36708 -- Initialized formset to None in ChangeList.__init__(). Thanks Antoliny for the review. --- django/contrib/admin/options.py | 19 ++++++------------- django/contrib/admin/views/main.py | 2 +- tests/admin_changelist/tests.py | 5 ----- 3 files changed, 7 insertions(+), 19 deletions(-) diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 6c202c8e61..2de07fde7e 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -2050,11 +2050,6 @@ class ModelAdmin(BaseModelAdmin): # me back" button on the action confirmation page. return HttpResponseRedirect(request.get_full_path()) - # If we're allowing changelist editing, we need to construct a formset - # for the changelist given all the fields to be edited. Then we'll - # use the formset to validate/process POSTed data. - formset = cl.formset = None - # Handle POSTed bulk-edit data. if request.method == "POST" and cl.list_editable and "_save" in request.POST: if not self.has_change_permission(request): @@ -2063,13 +2058,11 @@ class ModelAdmin(BaseModelAdmin): modified_objects = self._get_list_editable_queryset( request, FormSet.get_default_prefix() ) - formset = cl.formset = FormSet( - request.POST, request.FILES, queryset=modified_objects - ) - if formset.is_valid(): + cl.formset = FormSet(request.POST, request.FILES, queryset=modified_objects) + if cl.formset.is_valid(): changecount = 0 with transaction.atomic(using=router.db_for_write(self.model)): - for form in formset.forms: + for form in cl.formset.forms: if form.has_changed(): obj = self.save_form(request, form, change=True) self.save_model(request, obj, form, change=True) @@ -2095,11 +2088,11 @@ class ModelAdmin(BaseModelAdmin): # Handle GET -- construct a formset for display. elif cl.list_editable and self.has_change_permission(request): FormSet = self.get_changelist_formset(request) - formset = cl.formset = FormSet(queryset=cl.result_list) + cl.formset = FormSet(queryset=cl.result_list) # Build the list of media to be used by the formset. - if formset: - media = self.media + formset.media + if cl.formset: + media = self.media + cl.formset.media else: media = self.media diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index 8c9118808e..40a6b3bf3a 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -101,7 +101,7 @@ class ChangeList: self.preserved_filters = model_admin.get_preserved_filters(request) self.sortable_by = sortable_by self.search_help_text = search_help_text - + self.formset = None # Get search parameters from the query string. _search_form = self.search_form_class(request.GET) if not _search_form.is_valid(): diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py index 68f6ca453e..319d6259f6 100644 --- a/tests/admin_changelist/tests.py +++ b/tests/admin_changelist/tests.py @@ -240,7 +240,6 @@ class ChangeListTests(TestCase): request.user = self.superuser m = ChildAdmin(Child, custom_site) cl = m.get_changelist_instance(request) - cl.formset = None template = Template( "{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}" ) @@ -285,7 +284,6 @@ class ChangeListTests(TestCase): admin.site.empty_value_display = "???" m = ChildAdmin(Child, admin.site) cl = m.get_changelist_instance(request) - cl.formset = None template = Template( "{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}" ) @@ -310,7 +308,6 @@ class ChangeListTests(TestCase): request.user = self.superuser m = EmptyValueChildAdmin(Child, admin.site) cl = m.get_changelist_instance(request) - cl.formset = None template = Template( "{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}" ) @@ -341,7 +338,6 @@ class ChangeListTests(TestCase): request.user = self.superuser m = ChildAdmin(Child, custom_site) cl = m.get_changelist_instance(request) - cl.formset = None template = Template( "{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}" ) @@ -370,7 +366,6 @@ class ChangeListTests(TestCase): request = self._mocked_authenticated_request("/grandchild/", self.superuser) m = GrandChildAdmin(GrandChild, custom_site) cl = m.get_changelist_instance(request) - cl.formset = None template = Template( "{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}" )