From 4187da258fe212d494cb578a0bc2b52c4979ab95 Mon Sep 17 00:00:00 2001
From: antoliny0919
Date: Mon, 28 Jul 2025 07:59:26 +0900
Subject: Fixed #35892 -- Supported Widget.use_fieldset in admin forms.
---
tests/admin_views/admin.py | 6 ++++
tests/admin_views/models.py | 16 +++++++++
tests/admin_views/tests.py | 25 ++++++++++++++
tests/admin_widgets/tests.py | 40 ++++++++++++++--------
tests/auth_tests/test_views.py | 6 ++++
.../widget_tests/test_clearablefileinput.py | 15 ++++----
6 files changed, 87 insertions(+), 21 deletions(-)
(limited to 'tests')
diff --git a/tests/admin_views/admin.py b/tests/admin_views/admin.py
index b6d009b388..69570a8062 100644
--- a/tests/admin_views/admin.py
+++ b/tests/admin_views/admin.py
@@ -47,6 +47,7 @@ from .models import (
Color2,
ComplexSortedPerson,
Country,
+ Course,
CoverLetter,
CustomArticle,
CyclicOne,
@@ -1190,6 +1191,10 @@ class CamelCaseAdmin(admin.ModelAdmin):
filter_horizontal = ["m2m"]
+class CourseAdmin(admin.ModelAdmin):
+ radio_fields = {"difficulty": admin.VERTICAL}
+
+
site = admin.AdminSite(name="admin")
site.site_url = "/my-site-url/"
site.register(Article, ArticleAdmin)
@@ -1280,6 +1285,7 @@ site.register(ChapterXtra1, ChapterXtra1Admin)
site.register(Pizza, PizzaAdmin)
site.register(ReadOnlyPizza, ReadOnlyPizzaAdmin)
site.register(ReadablePizza)
+site.register(Course, CourseAdmin)
site.register(Topping, ToppingAdmin)
site.register(Album, AlbumAdmin)
site.register(Song)
diff --git a/tests/admin_views/models.py b/tests/admin_views/models.py
index 8f102dece3..4e2d13efa8 100644
--- a/tests/admin_views/models.py
+++ b/tests/admin_views/models.py
@@ -623,6 +623,22 @@ class CyclicTwo(models.Model):
return self.name
+class Course(models.Model):
+ DIFFICULTY_CHOICES = [
+ ("beginner", "Beginner Class"),
+ ("intermediate", "Intermediate Class"),
+ ("advanced", "Advanced Class"),
+ ]
+
+ title = models.CharField(max_length=100)
+ materials = models.FileField(upload_to="test_upload")
+ difficulty = models.CharField(
+ max_length=20, choices=DIFFICULTY_CHOICES, null=True, blank=True
+ )
+ categories = models.ManyToManyField(Category, blank=True)
+ start_datetime = models.DateTimeField(null=True, blank=True)
+
+
class Topping(models.Model):
name = models.CharField(max_length=20)
diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
index 26fdacfa00..db638c1ea8 100644
--- a/tests/admin_views/tests.py
+++ b/tests/admin_views/tests.py
@@ -70,6 +70,7 @@ from .models import (
Color,
ComplexSortedPerson,
Country,
+ Course,
CoverLetter,
CustomArticle,
CyclicOne,
@@ -6908,6 +6909,30 @@ class SeleniumTests(AdminSeleniumTestCase):
name_input_value = name_input.get_attribute("value")
self.assertEqual(name_input_value, "Test section 1")
+ def test_use_fieldset_fields_render(self):
+ from selenium.webdriver.common.by import By
+
+ self.admin_login(
+ username="super", password="secret", login_url=reverse("admin:index")
+ )
+ course = Course.objects.create(
+ title="Django Class", materials="django_documents"
+ )
+ expected_legend_tags_text = [
+ "Materials:",
+ "Difficulty:",
+ "Categories:",
+ "Start datetime:",
+ ]
+ url = reverse("admin:admin_views_course_change", args=(course.pk,))
+ self.selenium.get(self.live_server_url + url)
+ fieldsets = self.selenium.find_elements(
+ By.CSS_SELECTOR, "fieldset.aligned fieldset"
+ )
+ for index, fieldset in enumerate(fieldsets):
+ legend = fieldset.find_element(By.TAG_NAME, "legend")
+ self.assertEqual(legend.text, expected_legend_tags_text[index])
+
@screenshot_cases(["desktop_size", "mobile_size", "rtl", "dark", "high_contrast"])
@override_settings(MESSAGE_LEVEL=10)
def test_messages(self):
diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py
index c47e0e3ec1..9a5c846bdd 100644
--- a/tests/admin_widgets/tests.py
+++ b/tests/admin_widgets/tests.py
@@ -399,7 +399,8 @@ class AdminDateWidgetTest(SimpleTestCase):
self.assertHTMLEqual(
w.render("test", datetime(2007, 12, 1, 9, 30)),
''
- '
',
)
# pass attrs to widget
@@ -407,7 +408,8 @@ class AdminDateWidgetTest(SimpleTestCase):
self.assertHTMLEqual(
w.render("test", datetime(2007, 12, 1, 9, 30)),
''
- '
',
)
@@ -418,7 +420,8 @@ class AdminTimeWidgetTest(SimpleTestCase):
self.assertHTMLEqual(
w.render("test", datetime(2007, 12, 1, 9, 30)),
''
- '
',
)
# pass attrs to widget
@@ -426,7 +429,8 @@ class AdminTimeWidgetTest(SimpleTestCase):
self.assertHTMLEqual(
w.render("test", datetime(2007, 12, 1, 9, 30)),
''
- '
',
)
@@ -435,12 +439,16 @@ class AdminSplitDateTimeWidgetTest(SimpleTestCase):
def test_render(self):
w = widgets.AdminSplitDateTime()
self.assertHTMLEqual(
- w.render("test", datetime(2007, 12, 1, 9, 30)),
+ w.render("test", datetime(2007, 12, 1, 9, 30), attrs={"id": "id_test"}),
''
- 'Date:
'
- 'Time:
',
+ ' '
+ '
'
+ ' '
+ '
',
)
def test_localization(self):
@@ -449,12 +457,16 @@ class AdminSplitDateTimeWidgetTest(SimpleTestCase):
with translation.override("de-at"):
w.is_localized = True
self.assertHTMLEqual(
- w.render("test", datetime(2007, 12, 1, 9, 30)),
+ w.render("test", datetime(2007, 12, 1, 9, 30), attrs={"id": "id_test"}),
''
- 'Datum:
'
- 'Zeit:
',
+ ' '
+ '
'
+ ' '
+ '',
)
diff --git a/tests/auth_tests/test_views.py b/tests/auth_tests/test_views.py
index 0a4f7d28c8..23dc858ddd 100644
--- a/tests/auth_tests/test_views.py
+++ b/tests/auth_tests/test_views.py
@@ -1550,6 +1550,12 @@ class ChangelistTests(MessagesTestMixin, AuthViewsTestCase):
self.assertContains(
response, f"{self.admin.username}\n› Change password"
)
+ # Usable password field.
+ self.assertContains(
+ response,
+ '