@@ -18,15 +18,47 @@ def __init__(self, attrs=None, date_format=None, time_format=None):
18
18
MultiWidget .__init__ (self , widgets , attrs )
19
19
20
20
21
- class ListWidget (Widget ):
22
- def __init__ (self , contained_widget , attrs = None ):
23
- self .contained_widget = contained_widget
24
- if isinstance (contained_widget , type ):
25
- self .contained_widget = self .contained_widget ()
26
- if self .is_localized :
27
- self .widget .is_localized = self .is_localized
28
- super (ListWidget , self ).__init__ (attrs )
21
+ class BaseContainerWidget (Widget ):
22
+ def __init__ (self , data_widget , attrs = None ):
23
+ if isinstance (data_widget , type ):
24
+ data_widget = data_widget ()
25
+ self .data_widget = data_widget
26
+ self .data_widget .is_localized = self .is_localized
27
+ super (BaseContainerWidget , self ).__init__ (attrs )
28
+
29
+ def id_for_label (self , id_ ):
30
+ # See the comment for RadioSelect.id_for_label()
31
+ if id_ :
32
+ id_ += '_0'
33
+ return id_
34
+
35
+ def format_output (self , rendered_widgets ):
36
+ """
37
+ Given a list of rendered widgets (as strings), returns a Unicode string
38
+ representing the HTML for the whole lot.
39
+
40
+ This hook allows you to format the HTML design of the widgets, if
41
+ needed.
42
+ """
43
+ return '' .join (rendered_widgets )
29
44
45
+ def _get_media (self ):
46
+ """
47
+ Media for a multiwidget is the combination of all media of
48
+ the subwidgets.
49
+ """
50
+ media = Media ()
51
+ media = media + self .data_widget .media
52
+ return media
53
+ media = property (_get_media )
54
+
55
+ def __deepcopy__ (self , memo ):
56
+ obj = super (BaseContainerWidget , self ).__deepcopy__ (memo )
57
+ obj .data_widget = copy .deepcopy (self .data_widget )
58
+ return obj
59
+
60
+
61
+ class ListWidget (BaseContainerWidget ):
30
62
def render (self , name , value , attrs = None ):
31
63
if value is not None and not isinstance (value , (list , tuple )):
32
64
raise TypeError (
@@ -41,19 +73,13 @@ def render(self, name, value, attrs=None):
41
73
for i , widget_value in enumerate (value ):
42
74
if id_ :
43
75
final_attrs = dict (final_attrs , id = '%s_%s' % (id_ , i ))
44
- output .append (self .contained_widget .render (
76
+ output .append (self .data_widget .render (
45
77
name + '_%s' % i , widget_value , final_attrs )
46
78
)
47
79
return mark_safe (self .format_output (output ))
48
80
49
- def id_for_label (self , id_ ):
50
- # See the comment for RadioSelect.id_for_label()
51
- if id_ :
52
- id_ += '_0'
53
- return id_
54
-
55
81
def value_from_datadict (self , data , files , name ):
56
- widget = self .contained_widget
82
+ widget = self .data_widget
57
83
i = 0
58
84
ret = []
59
85
while (name + '_%s' % i ) in data or (name + '_%s' % i ) in files :
@@ -67,69 +93,12 @@ def value_from_datadict(self, data, files, name):
67
93
i = i + 1
68
94
return ret
69
95
70
- def format_output (self , rendered_widgets ):
71
- """
72
- Given a list of rendered widgets (as strings), returns a Unicode string
73
- representing the HTML for the whole lot.
74
-
75
- This hook allows you to format the HTML design of the widgets, if
76
- needed.
77
- """
78
- return '' .join (rendered_widgets )
79
-
80
- def _get_media (self ):
81
- """
82
- Media for a multiwidget is the combination of all media of
83
- the subwidgets
84
- """
85
- media = Media ()
86
- for w in self .widgets :
87
- media = media + w .media
88
- return media
89
- media = property (_get_media )
90
-
91
- def __deepcopy__ (self , memo ):
92
- obj = super (ListWidget , self ).__deepcopy__ (memo )
93
- obj .contained_widget = copy .deepcopy (self .contained_widget )
94
- #obj.widget_type = copy.deepcopy(self.widget_type)
95
- return obj
96
-
97
-
98
- class MapWidget (Widget ):
99
- """
100
- A widget that is composed of multiple widgets.
101
-
102
- Its render() method is different than other widgets', because it has to
103
- figure out how to split a single value for display in multiple widgets.
104
- The ``value`` argument can be one of two things:
105
-
106
- * A list.
107
- * A normal value (e.g., a string) that has been "compressed" from
108
- a list of values.
109
-
110
- In the second case -- i.e., if the value is NOT a list -- render() will
111
- first "decompress" the value into a list before rendering it. It does so by
112
- calling the decompress() method, which MultiWidget subclasses must
113
- implement. This method takes a single "compressed" value and returns a
114
- list.
115
-
116
- When render() does its HTML rendering, each value in the list is rendered
117
- with the corresponding widget -- the first value is rendered in the first
118
- widget, the second value is rendered in the second widget, etc.
119
96
120
- Subclasses may implement format_output(), which takes the list of rendered
121
- widgets and returns a string of HTML that formats them any way you'd like.
122
-
123
- You'll probably want to use this class with MultiValueField.
124
- """
125
- def __init__ (self , contained_widget , attrs = None ):
97
+ class MapWidget (BaseContainerWidget ):
98
+ def __init__ (self , data_widget , attrs = None ):
126
99
self .key_widget = TextInput ()
127
100
self .key_widget .is_localized = self .is_localized
128
- if isinstance (contained_widget , type ):
129
- contained_widget = contained_widget ()
130
- self .data_widget = contained_widget
131
- self .data_widget .is_localized = self .is_localized
132
- super (MapWidget , self ).__init__ (attrs )
101
+ super (MapWidget , self ).__init__ (data_widget , attrs )
133
102
134
103
def render (self , name , value , attrs = None ):
135
104
if value is not None and not isinstance (value , dict ):
@@ -167,12 +136,6 @@ def render(self, name, value, attrs=None):
167
136
output .append (mark_safe ('' .join (group )))
168
137
return mark_safe (self .format_output (output ))
169
138
170
- def id_for_label (self , id_ ):
171
- # See the comment for RadioSelect.id_for_label()
172
- if id_ :
173
- id_ += '_0'
174
- return id_
175
-
176
139
def value_from_datadict (self , data , files , name ):
177
140
i = 0
178
141
ret = {}
@@ -188,29 +151,17 @@ def value_from_datadict(self, data, files, name):
188
151
i = i + 1
189
152
return ret
190
153
191
- def format_output (self , rendered_widgets ):
192
- """
193
- Given a list of rendered widgets (as strings), returns a Unicode string
194
- representing the HTML for the whole lot.
195
-
196
- This hook allows you to format the HTML design of the widgets, if
197
- needed.
198
- """
199
- return '' .join (rendered_widgets )
200
-
201
154
def _get_media (self ):
202
155
"""
203
156
Media for a multiwidget is the combination of all media of
204
157
the subwidgets.
205
158
"""
206
- media = Media ()
207
- for w in self .widgets :
208
- media = media + w .media
159
+ media = super (MapWidget , self )._get_media ()
160
+ media = media + self .key_widget .media
209
161
return media
210
162
media = property (_get_media )
211
163
212
164
def __deepcopy__ (self , memo ):
213
165
obj = super (MapWidget , self ).__deepcopy__ (memo )
214
166
obj .key_widget = copy .deepcopy (self .key_widget )
215
- obj .data_widget = copy .deepcopy (self .data_widget )
216
167
return obj
0 commit comments