diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py index 095be4433d..8967200318 100644 --- a/django/contrib/admin/widgets.py +++ b/django/contrib/admin/widgets.py @@ -376,7 +376,7 @@ class AdminURLFieldWidget(forms.URLInput): def render(self, name, value, attrs=None): html = super(AdminURLFieldWidget, self).render(name, value, attrs) if value: - value = force_text(self._format_value(value)) + value = force_text(self.format_value(value)) final_attrs = {'href': smart_urlquote(value)} html = format_html( '

{} {}
{} {}

', diff --git a/django/forms/widgets.py b/django/forms/widgets.py index 4ec2cce075..68abd3b7dc 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -15,6 +15,9 @@ from django.templatetags.static import static from django.utils import datetime_safe, formats, six from django.utils.datastructures import MultiValueDict from django.utils.dates import MONTHS +from django.utils.deprecation import ( + RemovedInDjango20Warning, RenameMethodsBase, +) from django.utils.encoding import ( force_str, force_text, python_2_unicode_compatible, ) @@ -174,7 +177,13 @@ class SubWidget(object): return self.parent_widget.render(*args) -class Widget(six.with_metaclass(MediaDefiningClass)): +class RenameWidgetMethods(MediaDefiningClass, RenameMethodsBase): + renamed_methods = ( + ('_format_value', 'format_value', RemovedInDjango20Warning), + ) + + +class Widget(six.with_metaclass(RenameWidgetMethods)): needs_multipart_form = False # Determines does this widget need multipart form is_localized = False is_required = False @@ -248,7 +257,7 @@ class Input(Widget): """ input_type = None # Subclasses must define this. - def _format_value(self, value): + def format_value(self, value): if self.is_localized: return formats.localize_input(value) return value @@ -259,7 +268,7 @@ class Input(Widget): final_attrs = self.build_attrs(attrs, type=self.input_type, name=name) if value != '': # Only add the 'value' attribute if a value is non-empty. - final_attrs['value'] = force_text(self._format_value(value)) + final_attrs['value'] = force_text(self.format_value(value)) return format_html('', flatatt(final_attrs)) @@ -443,7 +452,7 @@ class DateTimeBaseInput(TextInput): super(DateTimeBaseInput, self).__init__(attrs) self.format = format if format else None - def _format_value(self, value): + def format_value(self, value): return formats.localize_input(value, self.format or formats.get_format(self.format_key)[0]) diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index 97534185b2..23dd56576b 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -163,6 +163,8 @@ details on these changes. * In multi-table inheritance, implicit promotion of a ``OneToOneField`` to a ``parent_link`` will be removed. +* Support for ``Widget._format_value()`` will be removed. + .. _deprecation-removed-in-1.10: 1.10 diff --git a/docs/ref/forms/widgets.txt b/docs/ref/forms/widgets.txt index f2b132ce3d..0bdce71f87 100644 --- a/docs/ref/forms/widgets.txt +++ b/docs/ref/forms/widgets.txt @@ -228,6 +228,17 @@ foundation for custom widgets. In older versions, this attribute was only defined on the date and time widgets (as ``False``). + .. method:: format_value(value) + + Cleans and returns a value for use in the widget template. ``value`` + isn't guaranteed to be valid input, therefore subclass implementations + should program defensively. + + .. versionchanged:: 1.10 + + In older versions, this method is a private API named + ``_format_value()``. The old name will work until Django 2.0. + .. method:: id_for_label(self, id_) Returns the HTML ID attribute of this widget for use by a ``