From e80de93af6a0a21a9063a55c4d6d20e3927243e9 Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Fri, 21 Mar 2014 19:07:13 -0400
Subject: [PATCH] Removed hard-coded help_text for ManyToManyFields that use a
 SelectMultiple widget

Per deprecation timeline; refs #9321.
---
 django/forms/models.py           |  8 ++----
 tests/admin_widgets/tests.py     | 12 --------
 tests/forms_tests/tests/tests.py |  8 +++---
 tests/model_forms/models.py      |  5 ----
 tests/model_forms/tests.py       | 48 ++++++--------------------------
 5 files changed, 15 insertions(+), 66 deletions(-)

diff --git a/django/forms/models.py b/django/forms/models.py
index 6a3dc62342..4f5cb26146 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -15,12 +15,12 @@ from django.forms.forms import DeclarativeFieldsMetaclass, BaseForm
 from django.forms.formsets import BaseFormSet, formset_factory
 from django.forms.utils import ErrorList
 from django.forms.widgets import (SelectMultiple, HiddenInput,
-    MultipleHiddenInput, CheckboxSelectMultiple)
+    MultipleHiddenInput)
 from django.utils import six
 from django.utils.deprecation import RemovedInDjango18Warning
 from django.utils.encoding import smart_text, force_text
 from django.utils.text import get_text_list, capfirst
-from django.utils.translation import ugettext_lazy as _, ugettext, string_concat
+from django.utils.translation import ugettext_lazy as _, ugettext
 
 
 __all__ = (
@@ -1196,10 +1196,6 @@ class ModelMultipleChoiceField(ModelChoiceField):
         super(ModelMultipleChoiceField, self).__init__(queryset, None,
             cache_choices, required, widget, label, initial, help_text,
             *args, **kwargs)
-        # Remove this in Django 1.8
-        if isinstance(self.widget, SelectMultiple) and not isinstance(self.widget, CheckboxSelectMultiple):
-            msg = _('Hold down "Control", or "Command" on a Mac, to select more than one.')
-            self.help_text = string_concat(self.help_text, ' ', msg)
 
     def to_python(self, value):
         if not value:
diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py
index 3c6846073f..939fb65a04 100644
--- a/tests/admin_widgets/tests.py
+++ b/tests/admin_widgets/tests.py
@@ -19,7 +19,6 @@ from django.core.files.uploadedfile import SimpleUploadedFile
 from django.db.models import CharField, DateField
 from django.test import TestCase as DjangoTestCase
 from django.test import override_settings
-from django.utils import six
 from django.utils import translation
 
 from . import models
@@ -169,17 +168,6 @@ class AdminFormfieldForDBFieldTests(TestCase):
     def testInheritance(self):
         self.assertFormfield(models.Album, 'backside_art', widgets.AdminFileWidget)
 
-    def test_m2m_widgets(self):
-        """m2m fields help text as it applies to admin app (#9321)."""
-        class AdvisorAdmin(admin.ModelAdmin):
-            filter_vertical = ['companies']
-
-        self.assertFormfield(models.Advisor, 'companies', widgets.FilteredSelectMultiple,
-                             filter_vertical=['companies'])
-        ma = AdvisorAdmin(models.Advisor, admin.site)
-        f = ma.formfield_for_dbfield(models.Advisor._meta.get_field('companies'), request=None)
-        self.assertEqual(six.text_type(f.help_text), ' Hold down "Control", or "Command" on a Mac, to select more than one.')
-
 
 @override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
 class AdminFormfieldForDBFieldWithRequestTests(DjangoTestCase):
diff --git a/tests/forms_tests/tests/tests.py b/tests/forms_tests/tests/tests.py
index 0be1f26d81..62b2251ede 100644
--- a/tests/forms_tests/tests/tests.py
+++ b/tests/forms_tests/tests/tests.py
@@ -111,12 +111,12 @@ class ModelFormCallableModelDefault(TestCase):
 <option value="1" selected="selected">ChoiceOption 1</option>
 <option value="2">ChoiceOption 2</option>
 <option value="3">ChoiceOption 3</option>
-</select><input type="hidden" name="initial-multi_choice" value="1" id="initial-id_multi_choice_0" /> <span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></p>
+</select><input type="hidden" name="initial-multi_choice" value="1" id="initial-id_multi_choice_0" /></p>
 <p><label for="id_multi_choice_int">Multi choice int:</label> <select multiple="multiple" name="multi_choice_int" id="id_multi_choice_int">
 <option value="1" selected="selected">ChoiceOption 1</option>
 <option value="2">ChoiceOption 2</option>
 <option value="3">ChoiceOption 3</option>
-</select><input type="hidden" name="initial-multi_choice_int" value="1" id="initial-id_multi_choice_int_0" /> <span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></p>""")
+</select><input type="hidden" name="initial-multi_choice_int" value="1" id="initial-id_multi_choice_int_0" /></p>""")
 
     def test_initial_instance_value(self):
         "Initial instances for model fields may also be instances (refs #7287)"
@@ -143,13 +143,13 @@ class ModelFormCallableModelDefault(TestCase):
 <option value="2" selected="selected">ChoiceOption 2</option>
 <option value="3" selected="selected">ChoiceOption 3</option>
 </select><input type="hidden" name="initial-multi_choice" value="2" id="initial-id_multi_choice_0" />
-<input type="hidden" name="initial-multi_choice" value="3" id="initial-id_multi_choice_1" /> <span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></p>
+<input type="hidden" name="initial-multi_choice" value="3" id="initial-id_multi_choice_1" /></p>
 <p><label for="id_multi_choice_int">Multi choice int:</label> <select multiple="multiple" name="multi_choice_int" id="id_multi_choice_int">
 <option value="1">ChoiceOption 1</option>
 <option value="2" selected="selected">ChoiceOption 2</option>
 <option value="3" selected="selected">ChoiceOption 3</option>
 </select><input type="hidden" name="initial-multi_choice_int" value="2" id="initial-id_multi_choice_int_0" />
-<input type="hidden" name="initial-multi_choice_int" value="3" id="initial-id_multi_choice_int_1" /> <span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></p>""")
+<input type="hidden" name="initial-multi_choice_int" value="3" id="initial-id_multi_choice_int_1" /></p>""")
 
 
 class FormsModelTestCase(TestCase):
diff --git a/tests/model_forms/models.py b/tests/model_forms/models.py
index 28feaa97cc..e71c482eb5 100644
--- a/tests/model_forms/models.py
+++ b/tests/model_forms/models.py
@@ -369,11 +369,6 @@ class ColourfulItem(models.Model):
     colours = models.ManyToManyField(Colour)
 
 
-class ArticleStatusNote(models.Model):
-    name = models.CharField(max_length=20)
-    status = models.ManyToManyField(ArticleStatus)
-
-
 class CustomErrorMessage(models.Model):
     name1 = models.CharField(max_length=50,
         validators=[validators.validate_slug],
diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py
index 4504ecb91d..58ed7cc0fb 100644
--- a/tests/model_forms/tests.py
+++ b/tests/model_forms/tests.py
@@ -24,7 +24,7 @@ from .models import (Article, ArticleStatus, Author, Author1, BetterWriter, BigI
     DerivedBook, DerivedPost, Document, ExplicitPK, FilePathModel, FlexibleDatePost, Homepage,
     ImprovedArticle, ImprovedArticleWithParentLink, Inventory, Person, Post, Price,
     Product, Publication, TextFile, Triple, Writer, WriterProfile,
-    Colour, ColourfulItem, ArticleStatusNote, DateTimePost, CustomErrorMessage,
+    Colour, ColourfulItem, DateTimePost, CustomErrorMessage,
     test_images, StumpJoke, Character)
 
 if test_images:
@@ -1004,7 +1004,7 @@ class ModelFormBasicTests(TestCase):
 <option value="%s" selected="selected">Entertainment</option>
 <option value="%s" selected="selected">It&#39;s a test</option>
 <option value="%s">Third test</option>
-</select> <span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></li>
+</select></li>
 <li>Status: <select name="status">
 <option value="" selected="selected">---------</option>
 <option value="1">Draft</option>
@@ -1040,7 +1040,7 @@ class ModelFormBasicTests(TestCase):
 <option value="%s">Entertainment</option>
 <option value="%s">It&#39;s a test</option>
 <option value="%s">Third test</option>
-</select> <span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></li>
+</select></li>
 <li>Status: <select name="status">
 <option value="" selected="selected">---------</option>
 <option value="1">Draft</option>
@@ -1084,7 +1084,7 @@ class ModelFormBasicTests(TestCase):
 <option value="%d" selected="selected">Entertainment</option>
 <option value="%d" selected="selected">It&39;s a test</option>
 <option value="%d">Third test</option>
-</select> <span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></li>"""
+</select></li>"""
             % (self.c1.pk, self.c2.pk, self.c3.pk))
 
     def test_basic_creation(self):
@@ -1147,7 +1147,7 @@ class ModelFormBasicTests(TestCase):
 <option value="%s">Entertainment</option>
 <option value="%s">It&#39;s a test</option>
 <option value="%s">Third test</option>
-</select><br /><span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></td></tr>
+</select></td></tr>
 <tr><th>Status:</th><td><select name="status">
 <option value="" selected="selected">---------</option>
 <option value="1">Draft</option>
@@ -1175,7 +1175,7 @@ class ModelFormBasicTests(TestCase):
 <option value="%s" selected="selected">Entertainment</option>
 <option value="%s">It&#39;s a test</option>
 <option value="%s">Third test</option>
-</select> <span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></li>
+</select></li>
 <li>Status: <select name="status">
 <option value="" selected="selected">---------</option>
 <option value="1">Draft</option>
@@ -1316,7 +1316,7 @@ class ModelFormBasicTests(TestCase):
 <option value="%s">Entertainment</option>
 <option value="%s">It&#39;s a test</option>
 <option value="%s">Third test</option>
-</select> <span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></li>
+</select> </li>
 <li>Status: <select name="status">
 <option value="" selected="selected">---------</option>
 <option value="1">Draft</option>
@@ -1341,7 +1341,7 @@ class ModelFormBasicTests(TestCase):
 <option value="%s">It&#39;s a test</option>
 <option value="%s">Third test</option>
 <option value="%s">Fourth</option>
-</select> <span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></li>
+</select></li>
 <li>Status: <select name="status">
 <option value="" selected="selected">---------</option>
 <option value="1">Draft</option>
@@ -2152,7 +2152,7 @@ class OtherModelFormTests(TestCase):
             """<p><label for="id_name">Name:</label> <input id="id_name" type="text" name="name" maxlength="50" /></p>
         <p><label for="id_colours">Colours:</label> <select multiple="multiple" name="colours" id="id_colours">
         <option value="%(blue_pk)s">Blue</option>
-        </select> <span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></p>"""
+        </select></p>"""
             % {'blue_pk': colour.pk})
 
 
@@ -2225,36 +2225,6 @@ class CustomCleanTests(TestCase):
         self.assertEqual(category.name, 'TEST')
 
 
-class M2mHelpTextTest(TestCase):
-    """Tests for ticket #9321."""
-    def test_multiple_widgets(self):
-        """Help text of different widgets for ManyToManyFields model fields"""
-        class StatusNoteForm(forms.ModelForm):
-            class Meta:
-                model = ArticleStatusNote
-                fields = '__all__'
-
-        class StatusNoteCBM2mForm(forms.ModelForm):
-            class Meta:
-                model = ArticleStatusNote
-                fields = '__all__'
-                widgets = {'status': forms.CheckboxSelectMultiple}
-
-        dreaded_help_text = '<span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span>'
-
-        # Default widget (SelectMultiple):
-        std_form = StatusNoteForm()
-        self.assertInHTML(dreaded_help_text, std_form.as_p())
-
-        # Overridden widget (CheckboxSelectMultiple, a subclass of
-        # SelectMultiple but with a UI that doesn't involve Control/Command
-        # keystrokes to extend selection):
-        form = StatusNoteCBM2mForm()
-        html = form.as_p()
-        self.assertInHTML('<ul id="id_status">', html)
-        self.assertInHTML(dreaded_help_text, html, count=0)
-
-
 class ModelFormInheritanceTests(TestCase):
     def test_form_subclass_inheritance(self):
         class Form(forms.Form):