summaryrefslogtreecommitdiff
path: root/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
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')
-rw-r--r--tests/admin_views/test_actions.py2
-rw-r--r--tests/admin_views/test_related_object_lookups.py4
-rw-r--r--tests/admin_views/tests.py15
-rw-r--r--tests/admin_widgets/tests.py4
-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
-rw-r--r--tests/model_fields/test_booleanfield.py5
-rw-r--r--tests/model_fields/tests.py5
-rw-r--r--tests/model_forms/test_modelchoicefield.py18
-rw-r--r--tests/model_forms/tests.py47
-rw-r--r--tests/model_formsets/tests.py6
-rw-r--r--tests/modeladmin/tests.py20
17 files changed, 178 insertions, 63 deletions
diff --git a/tests/admin_views/test_actions.py b/tests/admin_views/test_actions.py
index 467fe046ef..c2c18e0b74 100644
--- a/tests/admin_views/test_actions.py
+++ b/tests/admin_views/test_actions.py
@@ -294,7 +294,7 @@ class AdminActionsTest(TestCase):
self.assertContains(
response,
"""<label>Action: <select name="action" required>
-<option value="" selected>---------</option>
+<option value="" selected>- Select an option -</option>
<option value="delete_selected">Delete selected external
subscribers</option>
<option value="redirect_to">Redirect to (Awesome action)</option>
diff --git a/tests/admin_views/test_related_object_lookups.py b/tests/admin_views/test_related_object_lookups.py
index 2e6c0d07bd..eeba23f4f3 100644
--- a/tests/admin_views/test_related_object_lookups.py
+++ b/tests/admin_views/test_related_object_lookups.py
@@ -112,7 +112,7 @@ class SeleniumTests(AdminSeleniumTestCase):
self.assertHTMLEqual(
fk_dropdown.get_attribute("innerHTML"),
f"""
- <option value="" selected="">---------</option>
+ <option value="" selected="">- Select an option -</option>
<option value="{id_value}" selected>{interesting_name}</option>
""",
)
@@ -157,7 +157,7 @@ class SeleniumTests(AdminSeleniumTestCase):
self.assertHTMLEqual(
fk_dropdown.get_attribute("innerHTML"),
f"""
- <option value="" selected>---------</option>
+ <option value="" selected>- Select an option -</option>
<option value="{id_value}">{name}</option>
""",
)
diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
index bebd51b0df..399c485fea 100644
--- a/tests/admin_views/tests.py
+++ b/tests/admin_views/tests.py
@@ -26,6 +26,7 @@ from django.contrib.contenttypes.models import ContentType
from django.core import mail
from django.core.checks import Error
from django.core.files import temp as tempfile
+from django.db.models.utils import get_blank_choice_label
from django.forms.utils import ErrorList
from django.template.response import TemplateResponse
from django.test import (
@@ -6929,7 +6930,7 @@ class SeleniumTests(AdminSeleniumTestCase):
self.selenium.switch_to.window(self.selenium.window_handles[0])
select = Select(self.selenium.find_element(By.ID, "id_parent"))
self.assertEqual(ParentWithUUIDPK.objects.count(), 0)
- self.assertEqual(select.first_selected_option.text, "---------")
+ self.assertEqual(select.first_selected_option.text, get_blank_choice_label())
self.assertEqual(select.first_selected_option.get_attribute("value"), "")
def test_inline_with_popup_cancel_delete(self):
@@ -7179,7 +7180,7 @@ class SeleniumTests(AdminSeleniumTestCase):
self.assertHTMLEqual(
_get_HTML_inside_element_by_id(born_country_select_id),
f"""
- <option value="" selected="">---------</option>
+ <option value="" selected="">- Select an option -</option>
<option value="{argentina.pk}" selected="">Argentina</option>
""",
)
@@ -7198,7 +7199,7 @@ class SeleniumTests(AdminSeleniumTestCase):
# limit_choices_to.
self.assertHTMLEqual(
_get_HTML_inside_element_by_id(favorite_country_to_vacation_select_id),
- '<option value="" selected="">---------</option>',
+ '<option value="" selected="">- Select an option -</option>',
)
# Add new Country from the living_country select.
@@ -7218,7 +7219,7 @@ class SeleniumTests(AdminSeleniumTestCase):
self.assertHTMLEqual(
_get_HTML_inside_element_by_id(born_country_select_id),
f"""
- <option value="" selected="">---------</option>
+ <option value="" selected="">- Select an option -</option>
<option value="{argentina.pk}" selected="">Argentina</option>
<option value="{spain.pk}">Spain</option>
""",
@@ -7240,7 +7241,7 @@ class SeleniumTests(AdminSeleniumTestCase):
# limit_choices_to.
self.assertHTMLEqual(
_get_HTML_inside_element_by_id(favorite_country_to_vacation_select_id),
- '<option value="" selected="">---------</option>',
+ '<option value="" selected="">- Select an option -</option>',
)
# Edit second Country created from living_country select.
@@ -7261,7 +7262,7 @@ class SeleniumTests(AdminSeleniumTestCase):
self.assertHTMLEqual(
_get_HTML_inside_element_by_id(born_country_select_id),
f"""
- <option value="" selected="">---------</option>
+ <option value="" selected="">- Select an option -</option>
<option value="{argentina.pk}" selected="">Argentina</option>
<option value="{italy.pk}">Italy</option>
""",
@@ -7281,7 +7282,7 @@ class SeleniumTests(AdminSeleniumTestCase):
# favorite_country_to_vacation field has no options.
self.assertHTMLEqual(
_get_HTML_inside_element_by_id(favorite_country_to_vacation_select_id),
- '<option value="" selected="">---------</option>',
+ '<option value="" selected="">- Select an option -</option>',
)
# Add a new Asian country.
diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py
index 5a8b29b83a..b1db728f67 100644
--- a/tests/admin_widgets/tests.py
+++ b/tests/admin_widgets/tests.py
@@ -1975,8 +1975,8 @@ class RelatedFieldWidgetSeleniumTests(AdminWidgetSeleniumTestCase):
# Chrome and Safari don't update related object links when selecting
# the same option as previously submitted. As a consequence, the
- # "pencil" and "eye" buttons remain disable, so select "---------"
- # first.
+ # "pencil" and "eye" buttons remain disable, so select
+ # "- Select an option -" first.
select = Select(self.selenium.find_element(By.ID, "id_user"))
select.select_by_index(0)
select.select_by_value("newuser")
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>
diff --git a/tests/model_fields/test_booleanfield.py b/tests/model_fields/test_booleanfield.py
index 30eb009eb7..d0ed6e86cc 100644
--- a/tests/model_fields/test_booleanfield.py
+++ b/tests/model_fields/test_booleanfield.py
@@ -1,6 +1,7 @@
from django import forms
from django.core.exceptions import ValidationError
from django.db import IntegrityError, models, transaction
+from django.db.models.utils import get_blank_choice_label
from django.test import SimpleTestCase, TestCase
from .models import BooleanModel, FksToBooleans, NullBooleanModel
@@ -48,7 +49,9 @@ class BooleanFieldTests(TestCase):
"""
choices = [(1, "Si"), (2, "No")]
f = models.BooleanField(choices=choices)
- self.assertEqual(f.formfield().choices, [("", "---------")] + choices)
+ self.assertEqual(
+ f.formfield().choices, [("", get_blank_choice_label())] + choices
+ )
def test_nullbooleanfield_formfield(self):
f = models.BooleanField(null=True)
diff --git a/tests/model_fields/tests.py b/tests/model_fields/tests.py
index b27c07a92f..fa7436343a 100644
--- a/tests/model_fields/tests.py
+++ b/tests/model_fields/tests.py
@@ -391,7 +391,10 @@ class GetChoicesTests(SimpleTestCase):
def test_lazy_strings_not_evaluated(self):
lazy_func = lazy(lambda x: 0 / 0, int) # raises ZeroDivisionError if evaluated.
f = models.CharField(choices=[(lazy_func("group"), [("a", "A"), ("b", "B")])])
- self.assertEqual(f.get_choices(include_blank=True)[0], ("", "---------"))
+ self.assertEqual(
+ f.get_choices(include_blank=True)[0],
+ ("", models.utils.get_blank_choice_label()),
+ )
class GetChoicesOrderingTests(TestCase):
diff --git a/tests/model_forms/test_modelchoicefield.py b/tests/model_forms/test_modelchoicefield.py
index 7f66b5b078..40c625da7c 100644
--- a/tests/model_forms/test_modelchoicefield.py
+++ b/tests/model_forms/test_modelchoicefield.py
@@ -2,6 +2,7 @@ import datetime
from django import forms
from django.core.exceptions import ValidationError
+from django.db.models.utils import get_blank_choice_label
from django.forms.models import ModelChoiceIterator, ModelChoiceIteratorValue
from django.forms.widgets import CheckboxSelectMultiple
from django.template import Context, Template
@@ -24,7 +25,7 @@ class ModelChoiceFieldTests(TestCase):
self.assertEqual(
list(f.choices),
[
- ("", "---------"),
+ ("", get_blank_choice_label()),
(self.c1.pk, "Entertainment"),
(self.c2.pk, "A test"),
(self.c3.pk, "Third"),
@@ -102,7 +103,7 @@ class ModelChoiceFieldTests(TestCase):
self.assertEqual(
list(f.choices),
[
- ("", "---------"),
+ ("", get_blank_choice_label()),
(self.c1.pk, "Entertainment"),
(self.c2.pk, "A test"),
],
@@ -118,7 +119,7 @@ class ModelChoiceFieldTests(TestCase):
self.assertEqual(
list(gen_two),
[
- ("", "---------"),
+ ("", get_blank_choice_label()),
(self.c1.pk, "Entertainment"),
(self.c2.pk, "A test"),
],
@@ -130,7 +131,7 @@ class ModelChoiceFieldTests(TestCase):
self.assertEqual(
list(f.choices),
[
- ("", "---------"),
+ ("", get_blank_choice_label()),
(self.c1.pk, "category Entertainment"),
(self.c2.pk, "category A test"),
(self.c3.pk, "category Third"),
@@ -143,7 +144,7 @@ class ModelChoiceFieldTests(TestCase):
self.assertEqual(
list(f.choices),
[
- ("", "---------"),
+ ("", get_blank_choice_label()),
(self.c1.pk, "Entertainment"),
(self.c2.pk, "A test"),
(self.c3.pk, "Third"),
@@ -154,7 +155,7 @@ class ModelChoiceFieldTests(TestCase):
self.assertEqual(
list(f.choices),
[
- ("", "---------"),
+ ("", get_blank_choice_label()),
(self.c1.pk, "Entertainment"),
(self.c2.pk, "A test"),
(self.c3.pk, "Third"),
@@ -174,6 +175,7 @@ class ModelChoiceFieldTests(TestCase):
self.assertIs(bool(f.choices), True)
def test_choices_radio_blank(self):
+ blank_choice = [("", get_blank_choice_label())]
choices = [
(self.c1.pk, "Entertainment"),
(self.c2.pk, "A test"),
@@ -190,7 +192,7 @@ class ModelChoiceFieldTests(TestCase):
)
self.assertEqual(
list(f.choices),
- [("", "---------")] + choices if blank else choices,
+ (blank_choice + choices if blank else choices),
)
def test_deepcopies_widget(self):
@@ -424,7 +426,7 @@ class ModelChoiceFieldTests(TestCase):
self.assertCountEqual(
list(f.choices),
[
- ("", "---------"),
+ ("", get_blank_choice_label()),
(self.c1.pk, "Entertainment"),
(self.c2.pk, "A test"),
(self.c3.pk, "Third"),
diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py
index 3d4eb06cf4..466b7dc57b 100644
--- a/tests/model_forms/tests.py
+++ b/tests/model_forms/tests.py
@@ -14,6 +14,7 @@ from django.core.exceptions import (
from django.core.files.uploadedfile import SimpleUploadedFile
from django.db import connection, models
from django.db.models.query import EmptyQuerySet
+from django.db.models.utils import get_blank_choice_label
from django.forms.models import (
ModelFormMetaclass,
construct_instance,
@@ -343,7 +344,7 @@ class ModelFormBaseTest(TestCase):
self.assertEqual(
list(form.fields["author"].choices),
[
- ("", "---------"),
+ ("", get_blank_choice_label()),
(writer.pk, "Joe Doe"),
],
)
@@ -1531,7 +1532,7 @@ class ModelFormBasicTests(TestCase):
<li>Slug: <input type="text" name="slug" maxlength="50" required></li>
<li>Pub date: <input type="text" name="pub_date" required></li>
<li>Writer: <select name="writer" required>
- <option value="" selected>---------</option>
+ <option value="" selected>- Select an option -</option>
<option value="%s">Bob Woodward</option>
<option value="%s">Mike Royko</option>
</select></li>
@@ -1543,7 +1544,7 @@ class ModelFormBasicTests(TestCase):
<option value="%s">Third test</option>
</select></li>
<li>Status: <select name="status">
- <option value="" selected>---------</option>
+ <option value="" selected>- Select an option -</option>
<option value="1">Draft</option>
<option value="2">Pending</option>
<option value="3">Live</option>
@@ -1585,7 +1586,7 @@ class ModelFormBasicTests(TestCase):
<li>Pub date:
<input type="text" name="pub_date" value="1988-01-04" required></li>
<li>Writer: <select name="writer" required>
- <option value="">---------</option>
+ <option value="">- Select an option -</option>
<option value="%s">Bob Woodward</option>
<option value="%s" selected>Mike Royko</option>
</select></li>
@@ -1597,7 +1598,7 @@ class ModelFormBasicTests(TestCase):
<option value="%s">Third test</option>
</select></li>
<li>Status: <select name="status">
- <option value="" selected>---------</option>
+ <option value="" selected>- Select an option -</option>
<option value="1">Draft</option>
<option value="2">Pending</option>
<option value="3">Live</option>
@@ -1731,7 +1732,7 @@ class ModelFormBasicTests(TestCase):
</div>
<div>Writer:
<select name="writer" required>
- <option value="" selected>---------</option>
+ <option value="" selected>- Select an option -</option>
<option value="%s">Bob Woodward</option>
<option value="%s">Mike Royko</option>
</select>
@@ -1748,7 +1749,7 @@ class ModelFormBasicTests(TestCase):
</div>
<div>Status:
<select name="status">
- <option value="" selected>---------</option>
+ <option value="" selected>- Select an option -</option>
<option value="1">Draft</option><option value="2">Pending</option>
<option value="3">Live</option>
</select>
@@ -1781,7 +1782,7 @@ class ModelFormBasicTests(TestCase):
<li>Pub date:
<input type="text" name="pub_date" value="1988-01-04" required></li>
<li>Writer: <select name="writer" required>
- <option value="">---------</option>
+ <option value="">- Select an option -</option>
<option value="%s">Bob Woodward</option>
<option value="%s" selected>Mike Royko</option>
</select></li>
@@ -1793,7 +1794,7 @@ class ModelFormBasicTests(TestCase):
<option value="%s">Third test</option>
</select></li>
<li>Status: <select name="status">
- <option value="" selected>---------</option>
+ <option value="" selected>- Select an option -</option>
<option value="1">Draft</option>
<option value="2">Pending</option>
<option value="3">Live</option>
@@ -1957,7 +1958,7 @@ class ModelFormBasicTests(TestCase):
'<li>Slug: <input type="text" name="slug" maxlength="50" required></li>'
'<li>Pub date: <input type="text" name="pub_date" required></li>'
'<li>Writer: <select name="writer" required>'
- '<option value="" selected>---------</option>'
+ '<option value="" selected>- Select an option -</option>'
'<option value="%s">Bob Woodward</option>'
'<option value="%s">Mike Royko</option>'
"</select></li>"
@@ -1969,7 +1970,7 @@ class ModelFormBasicTests(TestCase):
'<option value="%s">Third test</option>'
"</select> </li>"
'<li>Status: <select name="status">'
- '<option value="" selected>---------</option>'
+ '<option value="" selected>- Select an option -</option>'
'<option value="1">Draft</option>'
'<option value="2">Pending</option>'
'<option value="3">Live</option>'
@@ -1986,7 +1987,7 @@ class ModelFormBasicTests(TestCase):
'<li>Slug: <input type="text" name="slug" maxlength="50" required></li>'
'<li>Pub date: <input type="text" name="pub_date" required></li>'
'<li>Writer: <select name="writer" required>'
- '<option value="" selected>---------</option>'
+ '<option value="" selected>- Select an option -</option>'
'<option value="%s">Bob Woodward</option>'
'<option value="%s">Carl Bernstein</option>'
'<option value="%s">Mike Royko</option>'
@@ -2000,7 +2001,7 @@ class ModelFormBasicTests(TestCase):
'<option value="%s">Fourth</option>'
"</select></li>"
'<li>Status: <select name="status">'
- '<option value="" selected>---------</option>'
+ '<option value="" selected>- Select an option -</option>'
'<option value="1">Draft</option>'
'<option value="2">Pending</option>'
'<option value="3">Live</option>'
@@ -2044,7 +2045,7 @@ class ModelFormBasicTests(TestCase):
self.assertEqual(call_count, 0)
self.assertEqual(
form.fields["animal"].choices,
- models.BLANK_CHOICE_DASH + [("LION", "Lion"), ("ZEBRA", "Zebra")],
+ [("", get_blank_choice_label())] + [("LION", "Lion"), ("ZEBRA", "Zebra")],
)
self.assertEqual(call_count, 1)
@@ -2410,7 +2411,7 @@ class ModelOneToOneFieldTests(TestCase):
"""
<p><label for="id_writer">Writer:</label>
<select name="writer" id="id_writer" required>
- <option value="" selected>---------</option>
+ <option value="" selected>- Select an option -</option>
<option value="%s">Bob Woodward</option>
<option value="%s">Mike Royko</option>
</select></p>
@@ -2437,7 +2438,7 @@ class ModelOneToOneFieldTests(TestCase):
"""
<p><label for="id_writer">Writer:</label>
<select name="writer" id="id_writer" required>
- <option value="">---------</option>
+ <option value="">- Select an option -</option>
<option value="%s" selected>Bob Woodward</option>
<option value="%s">Mike Royko</option>
</select></p>
@@ -2727,7 +2728,8 @@ class FileAndImageFieldTests(TestCase):
form = FPForm()
self.assertEqual(
- [name for _, name in form["path"].field.choices], ["---------", "models.py"]
+ [name for _, name in form["path"].field.choices],
+ [get_blank_choice_label(), "models.py"],
)
@skipUnless(test_images, "Pillow not installed")
@@ -3027,7 +3029,7 @@ class OtherModelFormTests(TestCase):
self.assertEqual(
tuple(field.choices),
(
- ("", "---------"),
+ ("", get_blank_choice_label()),
(multicolor_item.pk, "blue, red"),
(red_item.pk, "red"),
),
@@ -3041,14 +3043,19 @@ class OtherModelFormTests(TestCase):
field = forms.ModelChoiceField(Inventory.objects.all(), to_field_name="barcode")
self.assertEqual(
tuple(field.choices),
- (("", "---------"), (86, "Apple"), (87, "Core"), (22, "Pear")),
+ (
+ ("", get_blank_choice_label()),
+ (86, "Apple"),
+ (87, "Core"),
+ (22, "Pear"),
+ ),
)
form = InventoryForm(instance=core)
self.assertHTMLEqual(
str(form["parent"]),
"""<select name="parent" id="id_parent">
-<option value="">---------</option>
+<option value="">- Select an option -</option>
<option value="86" selected>Apple</option>
<option value="87">Core</option>
<option value="22">Pear</option>
diff --git a/tests/model_formsets/tests.py b/tests/model_formsets/tests.py
index 9436642573..75e4a42163 100644
--- a/tests/model_formsets/tests.py
+++ b/tests/model_formsets/tests.py
@@ -1267,9 +1267,9 @@ class ModelFormsetTest(TestCase):
formset.forms[0].as_p(),
'<p><label for="id_form-0-owner">Owner:</label>'
'<select name="form-0-owner" id="id_form-0-owner">'
- '<option value="" selected>---------</option>'
- '<option value="%s">Joe Perry at Giordanos</option>'
- '<option value="%s">Jack Berry at Giordanos</option>'
+ '<option value="" selected>- Select an option -</option>'
+ '<option value="%d">Joe Perry at Giordanos</option>'
+ '<option value="%d">Jack Berry at Giordanos</option>'
"</select></p>"
'<p><label for="id_form-0-age">Age:</label>'
'<input type="number" name="form-0-age" id="id_form-0-age" min="0"></p>'
diff --git a/tests/modeladmin/tests.py b/tests/modeladmin/tests.py
index 74bbc83efb..5ca7999bf0 100644
--- a/tests/modeladmin/tests.py
+++ b/tests/modeladmin/tests.py
@@ -18,6 +18,7 @@ from django.contrib.admin.widgets import (
)
from django.contrib.auth.models import User
from django.db import models
+from django.db.models.utils import get_blank_choice_label
from django.forms.widgets import Select
from django.test import RequestFactory, SimpleTestCase, TestCase
from django.test.utils import isolate_apps
@@ -636,7 +637,7 @@ class ModelAdminTests(TestCase):
'<div class="related-widget-wrapper" data-model-ref="band">'
'<select data-context="available-source" '
'name="main_band" id="id_main_band" required>'
- '<option value="" selected>---------</option>'
+ '<option value="" selected>- Select an option -</option>'
'<option value="%s">The Beatles</option>'
'<option value="%s">The Doors</option>'
"</select></div>" % (band2.id, self.band.id),
@@ -660,8 +661,8 @@ class ModelAdminTests(TestCase):
'<div class="related-widget-wrapper" data-model-ref="band">'
'<select data-context="available-source" '
'name="main_band" id="id_main_band" required>'
- '<option value="" selected>---------</option>'
- '<option value="%s">The Doors</option>'
+ '<option value="" selected>- Select an option -</option>'
+ '<option value="%d">The Doors</option>'
"</select></div>" % self.band.id,
)
@@ -708,30 +709,31 @@ class ModelAdminTests(TestCase):
# ForeignKey widgets in the admin are wrapped with
# RelatedFieldWidgetWrapper so they need to be handled properly when
# type checking. For Select fields, all of the choices lists have a
- # first entry of dashes.
+ # first entry of a translatable blank choice label.
+ blank_option = ("", get_blank_choice_label())
cma = ModelAdmin(Concert, self.site)
cmafa = cma.get_form(request)
self.assertEqual(type(cmafa.base_fields["main_band"].widget.widget), Select)
self.assertEqual(
list(cmafa.base_fields["main_band"].widget.choices),
- [("", "---------"), (self.band.id, "The Doors")],
+ [blank_option, (self.band.id, "The Doors")],
)
self.assertEqual(type(cmafa.base_fields["opening_band"].widget.widget), Select)
self.assertEqual(
list(cmafa.base_fields["opening_band"].widget.choices),
- [("", "---------"), (self.band.id, "The Doors")],
+ [blank_option, (self.band.id, "The Doors")],
)
self.assertEqual(type(cmafa.base_fields["day"].widget), Select)
self.assertEqual(
list(cmafa.base_fields["day"].widget.choices),
- [("", "---------"), (1, "Fri"), (2, "Sat")],
+ [blank_option, (1, "Fri"), (2, "Sat")],
)
self.assertEqual(type(cmafa.base_fields["transport"].widget), Select)
self.assertEqual(
list(cmafa.base_fields["transport"].widget.choices),
- [("", "---------"), (1, "Plane"), (2, "Train"), (3, "Bus")],
+ [blank_option, (1, "Plane"), (2, "Train"), (3, "Bus")],
)
def test_foreign_key_as_radio_field(self):
@@ -849,7 +851,7 @@ class ModelAdminTests(TestCase):
'class="related-widget-wrapper" data-model-ref="band"><select '
'name="main_band" data-context="available-source" required '
'id="id_main_band" data-custom-widget="true" multiple>'
- '<option value="">---------</option>'
+ '<option value="">- Select an option -</option>'
f'<option value="{self.band.pk}">The Doors</option>'
"</select></div></div>"
)