Commit a19f0d0c authored by Claude Paroz's avatar Claude Paroz
Browse files

Fixed #22137 -- Made Widget.is_hidden a read-only property

Thanks django at patjack.co.uk for the report and the review.
parent 75d0dcbf
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -235,7 +235,6 @@ class RelatedFieldWidgetWrapper(forms.Widget):
    admin interface.
    """
    def __init__(self, widget, rel, admin_site, can_add_related=None):
        self.is_hidden = widget.is_hidden
        self.needs_multipart_form = widget.needs_multipart_form
        self.attrs = widget.attrs
        self.choices = widget.choices
@@ -256,6 +255,10 @@ class RelatedFieldWidgetWrapper(forms.Widget):
        memo[id(self)] = obj
        return obj

    @property
    def is_hidden(self):
        return self.widget.is_hidden

    @property
    def media(self):
        return self.widget.media
+16 −5
Original line number Diff line number Diff line
@@ -166,7 +166,6 @@ class SubWidget(object):


class Widget(six.with_metaclass(MediaDefiningClass)):
    is_hidden = False             # Determines whether this corresponds to an <input type="hidden">.
    needs_multipart_form = False  # Determines does this widget need multipart form
    is_localized = False
    is_required = False
@@ -183,6 +182,18 @@ class Widget(six.with_metaclass(MediaDefiningClass)):
        memo[id(self)] = obj
        return obj

    @property
    def is_hidden(self):
        return self.input_type == 'hidden' if hasattr(self, 'input_type') else False

    @is_hidden.setter
    def is_hidden(self, *args):
        warnings.warn(
            "`is_hidden` property is now read-only (and checks `input_type`). "
            "Please update your code.",
            DeprecationWarning, stacklevel=2
        )

    def subwidgets(self, name, value, attrs=None, choices=()):
        """
        Yields all "subwidgets" of this widget. Used only by RadioSelect to
@@ -286,7 +297,6 @@ class PasswordInput(TextInput):

class HiddenInput(Input):
    input_type = 'hidden'
    is_hidden = True


class MultipleHiddenInput(HiddenInput):
@@ -778,6 +788,10 @@ class MultiWidget(Widget):
        self.widgets = [w() if isinstance(w, type) else w for w in widgets]
        super(MultiWidget, self).__init__(attrs)

    @property
    def is_hidden(self):
        return all(w.is_hidden for w in self.widgets)

    def render(self, name, value, attrs=None):
        if self.is_localized:
            for widget in self.widgets:
@@ -865,10 +879,7 @@ class SplitHiddenDateTimeWidget(SplitDateTimeWidget):
    """
    A Widget that splits datetime input into two <input type="hidden"> inputs.
    """
    is_hidden = True

    def __init__(self, attrs=None, date_format=None, time_format=None):
        super(SplitHiddenDateTimeWidget, self).__init__(attrs, date_format, time_format)
        for widget in self.widgets:
            widget.input_type = 'hidden'
            widget.is_hidden = True
+3 −0
Original line number Diff line number Diff line
@@ -1100,6 +1100,9 @@ Miscellaneous
  This widget now respects the form field's ``is_required`` attribute like
  other widgets.

* ``Widget.is_hidden`` is now a read-only property, getting its value by
  introspecting the presence of ``input_type == 'hidden'``.

* :meth:`~django.db.models.query.QuerySet.select_related` now chains in the
  same way as other similar calls like ``prefetch_related``. That is,
  ``select_related('foo', 'bar')`` is equivalent to