Fixed #22533 -- Added label_suffix parameter to form fields.
Fields can now receive the `label_suffix` attribute, which will override a form's `label_suffix`. This enhances the possibility to customize form's `label_suffix`, allowing to use such customizations while using shortcuts such as `{{ form.as_p }}`. Note that the field's own customization can be overridden at runtime by using the `label_prefix` parameter to `BoundField.label_tag()`. Refs #18134.
This commit is contained in:
parent
f2a8e47cfd
commit
5eb81ce445
|
@ -61,7 +61,7 @@ class Field(object):
|
||||||
|
|
||||||
def __init__(self, required=True, widget=None, label=None, initial=None,
|
def __init__(self, required=True, widget=None, label=None, initial=None,
|
||||||
help_text='', error_messages=None, show_hidden_initial=False,
|
help_text='', error_messages=None, show_hidden_initial=False,
|
||||||
validators=[], localize=False):
|
validators=[], localize=False, label_suffix=None):
|
||||||
# required -- Boolean that specifies whether the field is required.
|
# required -- Boolean that specifies whether the field is required.
|
||||||
# True by default.
|
# True by default.
|
||||||
# widget -- A Widget class, or instance of a Widget class, that should
|
# widget -- A Widget class, or instance of a Widget class, that should
|
||||||
|
@ -81,9 +81,12 @@ class Field(object):
|
||||||
# hidden widget with initial value after widget.
|
# hidden widget with initial value after widget.
|
||||||
# validators -- List of addtional validators to use
|
# validators -- List of addtional validators to use
|
||||||
# localize -- Boolean that specifies if the field should be localized.
|
# localize -- Boolean that specifies if the field should be localized.
|
||||||
|
# label_suffix -- Suffix to be added to the label. Overrides
|
||||||
|
# form's label_suffix.
|
||||||
self.required, self.label, self.initial = required, label, initial
|
self.required, self.label, self.initial = required, label, initial
|
||||||
self.show_hidden_initial = show_hidden_initial
|
self.show_hidden_initial = show_hidden_initial
|
||||||
self.help_text = help_text
|
self.help_text = help_text
|
||||||
|
self.label_suffix = label_suffix
|
||||||
widget = widget or self.widget
|
widget = widget or self.widget
|
||||||
if isinstance(widget, type):
|
if isinstance(widget, type):
|
||||||
widget = widget()
|
widget = widget()
|
||||||
|
|
|
@ -616,8 +616,10 @@ class BoundField(object):
|
||||||
label_suffix allows overriding the form's label_suffix.
|
label_suffix allows overriding the form's label_suffix.
|
||||||
"""
|
"""
|
||||||
contents = contents or self.label
|
contents = contents or self.label
|
||||||
|
if label_suffix is None:
|
||||||
|
label_suffix = (self.field.label_suffix if self.field.label_suffix is not None
|
||||||
|
else self.form.label_suffix)
|
||||||
# Only add the suffix if the label does not end in punctuation.
|
# Only add the suffix if the label does not end in punctuation.
|
||||||
label_suffix = label_suffix if label_suffix is not None else self.form.label_suffix
|
|
||||||
# Translators: If found as last label character, these punctuation
|
# Translators: If found as last label character, these punctuation
|
||||||
# characters will prevent the default label_suffix to be appended to the label
|
# characters will prevent the default label_suffix to be appended to the label
|
||||||
if label_suffix and contents and contents[-1] not in _(':?.!'):
|
if label_suffix and contents and contents[-1] not in _(':?.!'):
|
||||||
|
|
|
@ -652,8 +652,13 @@ Note that the label suffix is added only if the last character of the
|
||||||
label isn't a punctuation character (in English, those are ``.``, ``!``, ``?``
|
label isn't a punctuation character (in English, those are ``.``, ``!``, ``?``
|
||||||
or ``:``).
|
or ``:``).
|
||||||
|
|
||||||
You can also customize the ``label_suffix`` on a per-field basis using the
|
.. versionadded:: 1.8
|
||||||
``label_suffix`` parameter to :meth:`~django.forms.BoundField.label_tag`.
|
|
||||||
|
Fields can also define their own :attr:`~django.forms.Field.label_suffix`.
|
||||||
|
This will take precedence over :attr:`Form.label_suffix
|
||||||
|
<django.forms.Form.label_suffix>`. The suffix can also be overridden at runtime
|
||||||
|
using the ``label_suffix`` parameter to
|
||||||
|
:meth:`~django.forms.BoundField.label_tag`.
|
||||||
|
|
||||||
Notes on field ordering
|
Notes on field ordering
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -799,12 +804,12 @@ auto-generated label tag. An optional ``attrs`` dictionary may contain
|
||||||
additional attributes for the ``<label>`` tag.
|
additional attributes for the ``<label>`` tag.
|
||||||
|
|
||||||
The HTML that's generated includes the form's
|
The HTML that's generated includes the form's
|
||||||
:attr:`~django.forms.Form.label_suffix` (a colon, by default). The optional
|
:attr:`~django.forms.Form.label_suffix` (a colon, by default) or, if set, the
|
||||||
``label_suffix`` parameter allows you to override the form's
|
current field's :attr:`~django.forms.Field.label_suffix`. The optional
|
||||||
:attr:`~django.forms.Form.label_suffix`. For example, you can use an empty
|
``label_suffix`` parameter allows you to override any previously set
|
||||||
string to hide the label on selected fields. If you need to do this in a
|
suffix. For example, you can use an empty string to hide the label on selected
|
||||||
template, you could write a custom filter to allow passing parameters to
|
fields. If you need to do this in a template, you could write a custom
|
||||||
``label_tag``.
|
filter to allow passing parameters to ``label_tag``.
|
||||||
|
|
||||||
.. versionchanged:: 1.8
|
.. versionchanged:: 1.8
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,26 @@ We've specified ``auto_id=False`` to simplify the output::
|
||||||
<tr><th>Your Web site:</th><td><input type="url" name="url" /></td></tr>
|
<tr><th>Your Web site:</th><td><input type="url" name="url" /></td></tr>
|
||||||
<tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
|
<tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
|
||||||
|
|
||||||
|
``label_suffix``
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. attribute:: Field.label_suffix
|
||||||
|
|
||||||
|
.. versionadded:: 1.8
|
||||||
|
|
||||||
|
The ``label_suffix`` argument lets you override the form's
|
||||||
|
:attr:`~django.forms.Form.label_suffix` on a per-field basis::
|
||||||
|
|
||||||
|
>>> class ContactForm(forms.Form):
|
||||||
|
... age = forms.IntegerField()
|
||||||
|
... nationality = forms.CharField()
|
||||||
|
... captcha_answer = forms.IntegerField(label='2 + 2', label_suffix=' =')
|
||||||
|
>>> f = ContactForm(label_suffix='?')
|
||||||
|
>>> print(f.as_p())
|
||||||
|
<p><label for="id_age">Age?</label> <input id="id_age" name="age" type="number" /></p>
|
||||||
|
<p><label for="id_nationality">Nationality?</label> <input id="id_nationality" name="nationality" type="text" /></p>
|
||||||
|
<p><label for="id_captcha_answer">2 + 2 =</label> <input id="id_captcha_answer" name="captcha_answer" type="number" /></p>
|
||||||
|
|
||||||
``initial``
|
``initial``
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -118,6 +118,13 @@ Forms
|
||||||
the ``<label>`` tags for required fields will have this class present in its
|
the ``<label>`` tags for required fields will have this class present in its
|
||||||
attributes.
|
attributes.
|
||||||
|
|
||||||
|
* :class:`~django.forms.Field` now accepts a
|
||||||
|
:attr:`~django.forms.Field.label_suffix` argument, which will override the
|
||||||
|
form's :attr:`~django.forms.Form.label_suffix`. This enables customizing the
|
||||||
|
suffix on a per-field basis — previously it wasn't possible to override
|
||||||
|
a form's :attr:`~django.forms.Form.label_suffix` while using shortcuts such
|
||||||
|
as ``{{ form.as_p }}`` in templates.
|
||||||
|
|
||||||
Internationalization
|
Internationalization
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
@ -1100,18 +1100,25 @@ class FormsTestCase(TestCase):
|
||||||
class FavoriteForm(Form):
|
class FavoriteForm(Form):
|
||||||
color = CharField(label='Favorite color?')
|
color = CharField(label='Favorite color?')
|
||||||
animal = CharField(label='Favorite animal')
|
animal = CharField(label='Favorite animal')
|
||||||
|
answer = CharField(label='Secret answer', label_suffix=' =')
|
||||||
|
|
||||||
f = FavoriteForm(auto_id=False)
|
f = FavoriteForm(auto_id=False)
|
||||||
self.assertHTMLEqual(f.as_ul(), """<li>Favorite color? <input type="text" name="color" /></li>
|
self.assertHTMLEqual(f.as_ul(), """<li>Favorite color? <input type="text" name="color" /></li>
|
||||||
<li>Favorite animal: <input type="text" name="animal" /></li>""")
|
<li>Favorite animal: <input type="text" name="animal" /></li>
|
||||||
|
<li>Secret answer = <input type="text" name="answer" /></li>""")
|
||||||
|
|
||||||
f = FavoriteForm(auto_id=False, label_suffix='?')
|
f = FavoriteForm(auto_id=False, label_suffix='?')
|
||||||
self.assertHTMLEqual(f.as_ul(), """<li>Favorite color? <input type="text" name="color" /></li>
|
self.assertHTMLEqual(f.as_ul(), """<li>Favorite color? <input type="text" name="color" /></li>
|
||||||
<li>Favorite animal? <input type="text" name="animal" /></li>""")
|
<li>Favorite animal? <input type="text" name="animal" /></li>
|
||||||
|
<li>Secret answer = <input type="text" name="answer" /></li>""")
|
||||||
|
|
||||||
f = FavoriteForm(auto_id=False, label_suffix='')
|
f = FavoriteForm(auto_id=False, label_suffix='')
|
||||||
self.assertHTMLEqual(f.as_ul(), """<li>Favorite color? <input type="text" name="color" /></li>
|
self.assertHTMLEqual(f.as_ul(), """<li>Favorite color? <input type="text" name="color" /></li>
|
||||||
<li>Favorite animal <input type="text" name="animal" /></li>""")
|
<li>Favorite animal <input type="text" name="animal" /></li>
|
||||||
|
<li>Secret answer = <input type="text" name="answer" /></li>""")
|
||||||
|
|
||||||
f = FavoriteForm(auto_id=False, label_suffix='\u2192')
|
f = FavoriteForm(auto_id=False, label_suffix='\u2192')
|
||||||
self.assertHTMLEqual(f.as_ul(), '<li>Favorite color? <input type="text" name="color" /></li>\n<li>Favorite animal\u2192 <input type="text" name="animal" /></li>')
|
self.assertHTMLEqual(f.as_ul(), '<li>Favorite color? <input type="text" name="color" /></li>\n<li>Favorite animal\u2192 <input type="text" name="animal" /></li>\n<li>Secret answer = <input type="text" name="answer" /></li>')
|
||||||
|
|
||||||
def test_initial_data(self):
|
def test_initial_data(self):
|
||||||
# You can specify initial data for a field by using the 'initial' argument to a
|
# You can specify initial data for a field by using the 'initial' argument to a
|
||||||
|
|
Loading…
Reference in New Issue