diff --git a/django/contrib/admin/static/admin/js/change_form.js b/django/contrib/admin/static/admin/js/change_form.js index 0ba16efef9..96a4c62ef4 100644 --- a/django/contrib/admin/static/admin/js/change_form.js +++ b/django/contrib/admin/static/admin/js/change_form.js @@ -1,23 +1,9 @@ -/*global gettext*/ 'use strict'; { const inputTags = ['BUTTON', 'INPUT', 'SELECT', 'TEXTAREA']; const modelName = document.getElementById('django-admin-form-add-constants').dataset.modelName; - let submitted = false; - if (modelName) { const form = document.getElementById(modelName + '_form'); - - form.addEventListener('submit', (event) => { - event.preventDefault(); - if (submitted) { - const answer = window.confirm(gettext('You have already submitted this form. Are you sure you want to submit it again?')); - if (!answer) {return;} - }; - event.target.submit(); - submitted = true; - }); - for (const element of form.elements) { // HTMLElement.offsetParent returns null when the element is not // rendered. diff --git a/docs/releases/4.1.1.txt b/docs/releases/4.1.1.txt index ec1b61617d..3e11782eb2 100644 --- a/docs/releases/4.1.1.txt +++ b/docs/releases/4.1.1.txt @@ -18,3 +18,7 @@ Bugfixes * Fixed a regression in Django 4.1 that caused a crash of the ``test`` management command when running in parallel and ``multiprocessing`` start method is ``spawn`` (:ticket:`33891`). + +* Fixed a regression in Django 4.1 that caused an incorrect redirection to the + admin changelist view when using *"Save and continue editing"* and *"Save and + add another"* options (:ticket:`33893`). diff --git a/tests/admin_views/test_prevent_double_submission.py b/tests/admin_views/test_prevent_double_submission.py deleted file mode 100644 index 1052a977ba..0000000000 --- a/tests/admin_views/test_prevent_double_submission.py +++ /dev/null @@ -1,105 +0,0 @@ -from django.contrib.admin.tests import AdminSeleniumTestCase -from django.contrib.auth.models import User -from django.test import override_settings -from django.urls import reverse - -from .models import Bookmark - - -@override_settings(ROOT_URLCONF="admin_views.urls") -class SeleniumTests(AdminSeleniumTestCase): - available_apps = ["admin_views"] + AdminSeleniumTestCase.available_apps - - def setUp(self): - self.BOOKMARK_ADD_URL = reverse("admin:admin_views_bookmark_add") - self.BOOKMARK_LIST_URL = reverse("admin:admin_views_bookmark_changelist") - self.ALERT_MESSAGE = ( - "You have already submitted this form. " - "Are you sure you want to submit it again?" - ) - self.superuser = User.objects.create_superuser( - username="super", - password="secret", - email="super@example.com", - ) - self.admin_login( - username="super", - password="secret", - login_url=reverse("admin:index"), - ) - - def test_single_submit_click_is_success_without_alert(self): - from selenium.webdriver.common.by import By - - self.selenium.get(self.live_server_url + self.BOOKMARK_ADD_URL) - input_ = self.selenium.find_element(By.ID, "id_name") - input_.send_keys("Bookmark name") - save_button = self.selenium.find_element(By.CSS_SELECTOR, "input[name=_save]") - save_button.click() - self.assertEqual( - self.selenium.current_url, self.live_server_url + self.BOOKMARK_LIST_URL - ) - self.assertEqual(Bookmark.objects.count(), 1) - - def _double_click_submit(self): - from selenium.webdriver.common.action_chains import ActionChains - from selenium.webdriver.common.by import By - - self.selenium.get(self.live_server_url + self.BOOKMARK_ADD_URL) - input_ = self.selenium.find_element(By.ID, "id_name") - input_.send_keys("Bookmark name") - save_button = self.selenium.find_element(By.CSS_SELECTOR, "input[name=_save]") - ActionChains(self.selenium).double_click(save_button).perform() - - def test_confirm_double_submit_alert(self): - self._double_click_submit() - alert = self.selenium.switch_to.alert - self.assertEqual(alert.text, self.ALERT_MESSAGE) - alert.accept() - self.wait_page_ready() - - OBJECTS_CREATED = 1 - if self.browser == "chrome": - OBJECTS_CREATED = 2 - elif self.browser == "firefox": - pass - - self.assertEqual(Bookmark.objects.count(), OBJECTS_CREATED) - - def test_cancel_double_submit_alert(self): - self._double_click_submit() - alert = self.selenium.switch_to.alert - self.assertEqual(alert.text, self.ALERT_MESSAGE) - alert.dismiss() - self.wait_page_ready() - self.assertEqual(Bookmark.objects.count(), 1) - - def test_submit_and_go_back(self): - from selenium.webdriver.common.by import By - - self.selenium.get(self.live_server_url + self.BOOKMARK_ADD_URL) - input_ = self.selenium.find_element(By.ID, "id_name") - input_.send_keys("Bookmark name") - - # submit by first time - save_button = self.selenium.find_element(By.CSS_SELECTOR, "input[name=_save]") - save_button.click() - self.assertEqual(Bookmark.objects.count(), 1) - self.assertEqual( - self.selenium.current_url, self.live_server_url + self.BOOKMARK_LIST_URL - ) - - # go back - self.selenium.back() - self.assertEqual( - self.selenium.current_url, self.live_server_url + self.BOOKMARK_ADD_URL - ) - - # submit again - input_ = self.selenium.find_element(By.ID, "id_name") - input_.clear() - input_.send_keys("Other bookmark name") - save_button = self.selenium.find_element(By.CSS_SELECTOR, "input[name=_save]") - save_button.click() - - self.assertEqual(Bookmark.objects.count(), 2) diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index 88468e883c..3037ec1c3b 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -6432,6 +6432,45 @@ class SeleniumTests(AdminSeleniumTestCase): self.assertEqual(traveler.living_country.name, "Italy") self.assertEqual(traveler.favorite_country_to_vacation.name, "Qatar") + def test_redirect_on_add_view_add_another_button(self): + from selenium.webdriver.common.by import By + + self.admin_login( + username="super", password="secret", login_url=reverse("admin:index") + ) + add_url = reverse("admin7:admin_views_section_add") + self.selenium.get(self.live_server_url + add_url) + name_input = self.selenium.find_element(By.ID, "id_name") + name_input.send_keys("Test section 1") + self.selenium.find_element( + By.XPATH, '//input[@value="Save and add another"]' + ).click() + self.assertEqual(Section.objects.count(), 1) + name_input = self.selenium.find_element(By.ID, "id_name") + name_input.send_keys("Test section 2") + self.selenium.find_element( + By.XPATH, '//input[@value="Save and add another"]' + ).click() + self.assertEqual(Section.objects.count(), 2) + + def test_redirect_on_add_view_continue_button(self): + from selenium.webdriver.common.by import By + + self.admin_login( + username="super", password="secret", login_url=reverse("admin:index") + ) + add_url = reverse("admin7:admin_views_section_add") + self.selenium.get(self.live_server_url + add_url) + name_input = self.selenium.find_element(By.ID, "id_name") + name_input.send_keys("Test section 1") + self.selenium.find_element( + By.XPATH, '//input[@value="Save and continue editing"]' + ).click() + self.assertEqual(Section.objects.count(), 1) + name_input = self.selenium.find_element(By.ID, "id_name") + name_input_value = name_input.get_attribute("value") + self.assertEqual(name_input_value, "Test section 1") + @override_settings(ROOT_URLCONF="admin_views.urls") class ReadonlyTest(AdminFieldExtractionMixin, TestCase):