Browse Source

Fixed #13009 -- Added BoundField.widget_type property.

David Smith 5 years ago
parent
commit
a350bfa6f4

+ 5 - 0
django/forms/boundfield.py

@@ -1,4 +1,5 @@
 import datetime
+import re
 
 from django.forms.utils import flatatt, pretty_name
 from django.forms.widgets import Textarea, TextInput
@@ -227,6 +228,10 @@ class BoundField:
             attrs['disabled'] = True
         return attrs
 
+    @property
+    def widget_type(self):
+        return re.sub(r'widget$|input$', '', self.field.widget.__class__.__name__.lower())
+
 
 @html_safe
 class BoundWidget:

+ 17 - 0
docs/ref/forms/api.txt

@@ -972,6 +972,23 @@ Attributes of ``BoundField``
         >>> print(f['message'].name)
         message
 
+.. attribute:: BoundField.widget_type
+
+    .. versionadded:: 3.1
+
+    Returns the lowercased class name of the wrapped field's widget, with any
+    trailing ``input`` or ``widget`` removed. This may be used when building
+    forms where the layout is dependent upon the widget type. For example::
+
+        {% for field in form %}
+            {% if field.widget_type == 'checkbox' %}
+                # render one way
+            {% else %}
+                # render another way
+            {% endif %}
+        {% endfor %}
+
+
 Methods of ``BoundField``
 -------------------------
 

+ 3 - 0
docs/releases/3.1.txt

@@ -278,6 +278,9 @@ Forms
 * :attr:`.MultiWidget.widgets` now accepts a dictionary which allows
   customizing subwidget ``name`` attributes.
 
+* The new :attr:`.BoundField.widget_type` property can be used to dynamically
+  adjust form rendering based upon the widget type.
+
 Generic Views
 ~~~~~~~~~~~~~
 

+ 9 - 0
tests/forms_tests/tests/test_forms.py

@@ -3142,6 +3142,15 @@ Good luck picking a username that doesn&#x27;t already exist.</p>
         self.assertEqual(form['field'].id_for_label, 'myCustomID')
         self.assertEqual(form['field_none'].id_for_label, 'id_field_none')
 
+    def test_boundfield_widget_type(self):
+        class SomeForm(Form):
+            first_name = CharField()
+            birthday = SplitDateTimeField(widget=SplitHiddenDateTimeWidget)
+
+        f = SomeForm()
+        self.assertEqual(f['first_name'].widget_type, 'text')
+        self.assertEqual(f['birthday'].widget_type, 'splithiddendatetime')
+
     def test_label_tag_override(self):
         """
         BoundField label_suffix (if provided) overrides Form label_suffix