diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 256c3e0f61..fd0b24433f 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -11,7 +11,7 @@ from django.db.models.deletion import CASCADE from django.utils.encoding import smart_text from django.utils import six from django.utils.deprecation import RenameMethodsBase -from django.utils.translation import ugettext_lazy as _, string_concat +from django.utils.translation import ugettext_lazy as _ from django.utils.functional import curry, cached_property from django.core import exceptions from django import forms @@ -1348,9 +1348,6 @@ class ManyToManyField(RelatedField): super(ManyToManyField, self).__init__(**kwargs) - msg = _('Hold down "Control", or "Command" on a Mac, to select more than one.') - self.help_text = string_concat(self.help_text, ' ', msg) - def _get_path_info(self, direct=False): """ Called by both direct an indirect m2m traversal. diff --git a/django/forms/models.py b/django/forms/models.py index 93c8b89efe..68c1341cf7 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -18,7 +18,7 @@ from django.utils.encoding import smart_text, force_text from django.utils.datastructures import SortedDict from django.utils import six from django.utils.text import get_text_list, capfirst -from django.utils.translation import ugettext_lazy as _, ugettext +from django.utils.translation import ugettext_lazy as _, ugettext, string_concat __all__ = ( @@ -1104,6 +1104,9 @@ class ModelMultipleChoiceField(ModelChoiceField): super(ModelMultipleChoiceField, self).__init__(queryset, None, cache_choices, required, widget, label, initial, help_text, *args, **kwargs) + if isinstance(self.widget, SelectMultiple): + msg = _('Hold down "Control", or "Command" on a Mac, to select more than one.') + self.help_text = string_concat(self.help_text, ' ', msg) if self.help_text else msg def clean(self, value): if self.required and not value: diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index 095b6d0a33..5fa7ea16ac 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -392,6 +392,11 @@ these changes. * The ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` setting will be removed. +* Usage of the hard-coded *Hold down "Control", or "Command" on a Mac, to select + more than one.* string to override or append to user-provided ``help_text`` in + forms for ManyToMany model fields will not be performed by Django anymore + either at the model or forms layer. + 2.0 --- diff --git a/docs/releases/1.6.txt b/docs/releases/1.6.txt index 9950717420..a417e81f62 100644 --- a/docs/releases/1.6.txt +++ b/docs/releases/1.6.txt @@ -481,6 +481,44 @@ parameters. For example:: ``SQLite`` users need to check and update such queries. +.. _m2m-help_text: + +Help text of model form fields for ManyToManyField fields +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +HTML rendering of model form fields corresponding to +:class:`~django.db.models.ManyToManyField` ORM model fields used to get the +hard-coded sentence + + *Hold down "Control", or "Command" on a Mac, to select more than one.* + +(or its translation to the active locale) imposed as the help legend shown along +them if neither :attr:`model ` nor :attr:`form +` ``help_text`` attribute was specified by the +user (or appended to, if ``help_text`` was provided.) + +This happened always, possibly even with form fields implementing user +interactions that don't involve a keyboard and/or a mouse and was handled at the +model field layer. + +Starting with Django 1.6 this doesn't happen anymore. + +The change can affect you in a backward incompatible way if you employ custom +model form fields and/or widgets for ``ManyToManyField`` model fields whose UIs +do rely on the automatic provision of the mentioned hard-coded sentence. These +form field implementations need to adapt to the new scenario by providing their +own handling of the ``help_text`` attribute. + +Applications that use Django :doc:`model form ` +facilities together with Django built-in form :doc:`fields ` +and :doc:`widgets ` aren't affected but need to be aware of +what's described in :ref:`m2m-help_text-deprecation` below. + +This is because, as an temporary backward-compatible provision, the described +non-standard behavior has been preserved but moved to the model form field layer +and occurs only when the associated widget is +:class:`~django.forms.SelectMultiple` or a subclass. + Miscellaneous ~~~~~~~~~~~~~ @@ -707,3 +745,16 @@ you can set set the ``form_class`` attribute to a ``ModelForm`` that explicitly defines the fields to be used. Defining an ``UpdateView`` or ``CreateView`` subclass to be used with a model but without an explicit list of fields is deprecated. + +.. _m2m-help_text-deprecation: + +Munging of help text of model form fields for ManyToManyField fields +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +All special handling of the ``help_text`` attibute of ManyToManyField model +fields performed by standard model or model form fields as described in +:ref:`m2m-help_text` above is deprecated and will be removed in Django 1.8. + +Help text of these fields will need to be handled either by applications, custom +form fields or widgets, just like happens with the rest of the model field +types.