MCPcopy
hub / github.com/django/django / MultiWidget

Class MultiWidget

django/forms/widgets.py:979–1083  ·  view source on GitHub ↗

A widget that is composed of multiple widgets. In addition to the values added by Widget.get_context(), this widget adds a list of subwidgets to the context as widget['subwidgets']. These can be looped over and rendered like normal widgets. You'll probably want to use this cla

Source from the content-addressed store, hash-verified

977
978
979class MultiWidget(Widget):
980 """
981 A widget that is composed of multiple widgets.
982
983 In addition to the values added by Widget.get_context(), this widget
984 adds a list of subwidgets to the context as widget['subwidgets'].
985 These can be looped over and rendered like normal widgets.
986
987 You'll probably want to use this class with MultiValueField.
988 """
989
990 template_name = "django/forms/widgets/multiwidget.html"
991 use_fieldset = True
992
993 def __init__(self, widgets, attrs=None):
994 if isinstance(widgets, dict):
995 self.widgets_names = [("_%s" % name) if name else "" for name in widgets]
996 widgets = widgets.values()
997 else:
998 self.widgets_names = ["_%s" % i for i in range(len(widgets))]
999 self.widgets = [w() if isinstance(w, type) else w for w in widgets]
1000 super().__init__(attrs)
1001
1002 @property
1003 def is_hidden(self):
1004 return all(w.is_hidden for w in self.widgets)
1005
1006 def get_context(self, name, value, attrs):
1007 context = super().get_context(name, value, attrs)
1008 if self.is_localized:
1009 for widget in self.widgets:
1010 widget.is_localized = self.is_localized
1011 # value is a list/tuple of values, each corresponding to a widget
1012 # in self.widgets.
1013 if not isinstance(value, (list, tuple)):
1014 value = self.decompress(value)
1015
1016 final_attrs = context["widget"]["attrs"]
1017 input_type = final_attrs.pop("type", None)
1018 id_ = final_attrs.get("id")
1019 subwidgets = []
1020 for i, (widget_name, widget) in enumerate(
1021 zip(self.widgets_names, self.widgets)
1022 ):
1023 if input_type is not None:
1024 widget.input_type = input_type
1025 widget_name = name + widget_name
1026 try:
1027 widget_value = value[i]
1028 except IndexError:
1029 widget_value = None
1030 if id_:
1031 widget_attrs = final_attrs.copy()
1032 widget_attrs["id"] = "%s_%s" % (id_, i)
1033 else:
1034 widget_attrs = final_attrs
1035 subwidgets.append(
1036 widget.get_context(widget_name, widget_value, widget_attrs)["widget"]

Calls

no outgoing calls