summaryrefslogtreecommitdiff
path: root/tests/forms_tests
diff options
context:
space:
mode:
authorAnnabelle Wiegart <annabelle.wiegart@proton.me>2026-01-18 20:03:28 +0100
committerJacob Walls <jacobtylerwalls@gmail.com>2026-04-22 17:06:29 -0400
commit63c56cda133a85a158502891c40465bc0331d3d9 (patch)
tree04380903d14307b71416b2e048ce4be8361cf0df /tests/forms_tests
parentdc467fdc3b5744cec71fab876c23a14013e2510b (diff)
Fixed #35870 -- Made blank choice label in forms more accessible.
Added new constant django.db.models.fields.BLANK_CHOICE_LABEL for an accessible and translatable blank choice label in forms. Deprecated django.db.models.fields.BLANK_CHOICE_DASH constant. Added the immediately deprecated transitional setting USE_BLANK_CHOICE_DASH. Co-Authored-By: Marijke Luttekes <mail@marijkeluttekes.dev>
Diffstat (limited to 'tests/forms_tests')
-rw-r--r--tests/forms_tests/field_tests/test_typedchoicefield.py7
-rw-r--r--tests/forms_tests/locale/de/LC_MESSAGES/django.mobin0 -> 322 bytes
-rw-r--r--tests/forms_tests/locale/de/LC_MESSAGES/django.po14
-rw-r--r--tests/forms_tests/locale/de/__init__.py0
-rw-r--r--tests/forms_tests/tests/test_forms.py37
-rw-r--r--tests/forms_tests/tests/test_i18n.py38
-rw-r--r--tests/forms_tests/widget_tests/test_radioselect.py19
7 files changed, 106 insertions, 9 deletions
diff --git a/tests/forms_tests/field_tests/test_typedchoicefield.py b/tests/forms_tests/field_tests/test_typedchoicefield.py
index 3537623272..fe5cbe12ee 100644
--- a/tests/forms_tests/field_tests/test_typedchoicefield.py
+++ b/tests/forms_tests/field_tests/test_typedchoicefield.py
@@ -1,6 +1,7 @@
import decimal
from django.core.exceptions import ValidationError
+from django.db.models.utils import get_blank_choice_label
from django.forms import TypedChoiceField
from django.test import SimpleTestCase
@@ -62,7 +63,11 @@ class TypedChoiceFieldTest(SimpleTestCase):
self.assertFalse(f.has_changed("1", "1"))
f = TypedChoiceField(
- choices=[("", "---------"), ("a", "a"), ("b", "b")],
+ choices=[
+ ("", get_blank_choice_label()),
+ ("a", "a"),
+ ("b", "b"),
+ ],
coerce=str,
required=False,
initial=None,
diff --git a/tests/forms_tests/locale/de/LC_MESSAGES/django.mo b/tests/forms_tests/locale/de/LC_MESSAGES/django.mo
new file mode 100644
index 0000000000..f2695ea426
--- /dev/null
+++ b/tests/forms_tests/locale/de/LC_MESSAGES/django.mo
Binary files differ
diff --git a/tests/forms_tests/locale/de/LC_MESSAGES/django.po b/tests/forms_tests/locale/de/LC_MESSAGES/django.po
new file mode 100644
index 0000000000..e118e28d98
--- /dev/null
+++ b/tests/forms_tests/locale/de/LC_MESSAGES/django.po
@@ -0,0 +1,14 @@
+# This file is distributed under the same license as the Django package.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: django\n"
+"Report-Msgid-Bugs-To: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: de\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgid "- Select an option -"
+msgstr "- Wähle eine Option -"
diff --git a/tests/forms_tests/locale/de/__init__.py b/tests/forms_tests/locale/de/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/forms_tests/locale/de/__init__.py
diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py
index 14fbc19a59..2c1ec78650 100644
--- a/tests/forms_tests/tests/test_forms.py
+++ b/tests/forms_tests/tests/test_forms.py
@@ -1,11 +1,14 @@
import copy
import datetime
import json
+import textwrap
import uuid
+from django.conf import USE_BLANK_CHOICE_DASH_DEPRECATED_MSG
from django.core.exceptions import NON_FIELD_ERRORS
from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.validators import MaxValueValidator, RegexValidator
+from django.db.models.utils import get_blank_choice_label
from django.forms import (
BooleanField,
BoundField,
@@ -42,9 +45,10 @@ from django.forms.renderers import DjangoTemplates, get_default_renderer
from django.forms.utils import ErrorDict, ErrorList
from django.http import QueryDict
from django.template import Context, Template
-from django.test import SimpleTestCase
+from django.test import SimpleTestCase, ignore_warnings
from django.test.utils import override_settings
from django.utils.datastructures import MultiValueDict
+from django.utils.deprecation import RemovedInDjango70Warning
from django.utils.safestring import mark_safe
from . import jinja2_tests
@@ -797,6 +801,37 @@ aria-describedby="id_birthday_error">
</select>""",
)
+ # RemovedInDjango70Warning
+ @ignore_warnings(category=RemovedInDjango70Warning)
+ @override_settings(USE_BLANK_CHOICE_DASH=True)
+ def test_blank_choice_dash(self):
+ class SomeForm(Form):
+ somechoices = ChoiceField(
+ choices=(
+ ("0", get_blank_choice_label()),
+ ("1", "Test 1"),
+ ("2", "Test 2"),
+ )
+ )
+
+ f = SomeForm()
+
+ self.assertHTMLEqual(
+ f.as_p(),
+ textwrap.dedent("""
+ <p>
+ <label for="id_somechoices">Somechoices:</label>
+ <select name="somechoices" id="id_somechoices">
+ <option value="0">---------</option>
+ <option value="1">Test 1</option>
+ <option value="2">Test 2</option></select>
+ </p>"""),
+ )
+
+ self.assertWarnsMessage(
+ RemovedInDjango70Warning, USE_BLANK_CHOICE_DASH_DEPRECATED_MSG
+ )
+
def test_forms_with_radio(self):
# Add widget=RadioSelect to use that widget with a ChoiceField.
f = FrameworkForm(auto_id=False)
diff --git a/tests/forms_tests/tests/test_i18n.py b/tests/forms_tests/tests/test_i18n.py
index 5b8d92c0f6..fe6a67dd16 100644
--- a/tests/forms_tests/tests/test_i18n.py
+++ b/tests/forms_tests/tests/test_i18n.py
@@ -1,3 +1,6 @@
+import textwrap
+
+from django.db.models.utils import get_blank_choice_label
from django.forms import (
CharField,
ChoiceField,
@@ -122,6 +125,41 @@ class FormsI18nTests(SimpleTestCase):
CopyForm()
+ def test_blank_choice_label(self):
+ class SomeForm(Form):
+ somechoices = ChoiceField(
+ choices=(
+ ("0", get_blank_choice_label()),
+ ("1", "Test 1"),
+ ("2", "Test 2"),
+ )
+ )
+
+ f = SomeForm()
+
+ self.assertHTMLEqual(
+ f.as_p(),
+ textwrap.dedent("""
+ <p>
+ <label for="id_somechoices">Somechoices:</label>
+ <select name="somechoices" id="id_somechoices">
+ <option value="0">- Select an option -</option>
+ <option value="1">Test 1</option>
+ <option value="2">Test 2</option></select>
+ </p>"""),
+ )
+
+ with translation.override("de"):
+ self.assertHTMLEqual(
+ f.as_p(),
+ textwrap.dedent("""<p><label for="id_somechoices">Somechoices:</label>
+ <select name="somechoices" id="id_somechoices">
+ <option value="0">- Wähle eine Option -</option>
+ <option value="1">Test 1</option>
+ <option value="2">Test 2</option></select>
+ </p>"""),
+ )
+
@jinja2_tests
class Jinja2FormsI18nTests(FormsI18nTests):
diff --git a/tests/forms_tests/widget_tests/test_radioselect.py b/tests/forms_tests/widget_tests/test_radioselect.py
index be336151ef..a4d4919009 100644
--- a/tests/forms_tests/widget_tests/test_radioselect.py
+++ b/tests/forms_tests/widget_tests/test_radioselect.py
@@ -1,12 +1,13 @@
import datetime
+from django.db.models.utils import get_blank_choice_label
from django.forms import ChoiceField, Form, MultiWidget, RadioSelect, TextInput
from django.test import override_settings
from django.utils.safestring import mark_safe
from .test_choicewidget import ChoiceWidgetTest
-BLANK_CHOICE_DASH = (("", "------"),)
+BLANK_CHOICE = (("", get_blank_choice_label()),)
class RadioSelectTest(ChoiceWidgetTest):
@@ -16,7 +17,9 @@ class RadioSelectTest(ChoiceWidgetTest):
html = """
<div>
<div>
- <label><input type="radio" name="beatle" value="">------</label>
+ <label><input type="radio" name="beatle" value="">
+ - Select an option -
+ </label>
</div>
<div>
<label><input checked type="radio" name="beatle" value="J">John</label>
@@ -32,7 +35,7 @@ class RadioSelectTest(ChoiceWidgetTest):
</div>
</div>
"""
- beatles_with_blank = BLANK_CHOICE_DASH + self.beatles
+ beatles_with_blank = BLANK_CHOICE + self.beatles
for choices in (beatles_with_blank, dict(beatles_with_blank)):
with self.subTest(choices):
self.check_html(self.widget(choices=choices), "beatle", "J", html=html)
@@ -83,11 +86,13 @@ class RadioSelectTest(ChoiceWidgetTest):
"""
If value is None, none of the options are selected.
"""
- choices = BLANK_CHOICE_DASH + self.beatles
+ choices = BLANK_CHOICE + self.beatles
html = """
<div>
<div>
- <label><input checked type="radio" name="beatle" value="">------</label>
+ <label><input checked type="radio" name="beatle" value="">
+ - Select an option -
+ </label>
</div>
<div>
<label><input type="radio" name="beatle" value="J">John</label>
@@ -463,11 +468,11 @@ class RadioSelectTest(ChoiceWidgetTest):
def test_render_as_subwidget(self):
"""A RadioSelect as a subwidget of MultiWidget."""
- choices = BLANK_CHOICE_DASH + self.beatles
+ choices = BLANK_CHOICE + self.beatles
html = """
<div>
<div><label>
- <input type="radio" name="beatle_0" value="">------</label>
+ <input type="radio" name="beatle_0" value="">- Select an option -</label>
</div>
<div><label>
<input checked type="radio" name="beatle_0" value="J">John</label>