class MapWidget(BaseContainerWidget): def __init__(self, data_widget, attrs=None): self.key_widget = TextInput() self.key_widget.is_localized = self.is_localized super(MapWidget, self).__init__(data_widget, attrs) def render(self, name, value, attrs=None): if value is not None and not isinstance(value, dict): raise TypeError("Value supplied for %s must be a dict." % name) output = [] final_attrs = self.build_attrs(attrs) id_ = final_attrs.get('id', None) fieldset_attr = {} # in Python 3.X dict.items() returns dynamic *view objects* value = list(value.items()) value.append(('', '')) for i, (key, widget_value) in enumerate(value): if id_: fieldset_attr = dict( final_attrs, id='fieldset_%s_%s' % (id_, i) ) group = [] if not self.is_hidden: group.append( mark_safe('<fieldset %s>' % flatatt(fieldset_attr))) if id_: final_attrs = dict(final_attrs, id='%s_key_%s' % (id_, i)) group.append(self.key_widget.render( name + '_key_%s' % i, key, final_attrs) ) if id_: final_attrs = dict(final_attrs, id='%s_value_%s' % (id_, i)) group.append(self.data_widget.render( name + '_value_%s' % i, widget_value, final_attrs) ) if not self.is_hidden: group.append(mark_safe('</fieldset>')) output.append(mark_safe(''.join(group))) return mark_safe(self.format_output(output)) def value_from_datadict(self, data, files, name): i = 0 ret = {} while (name + '_key_%s' % i) in data: key = self.key_widget.value_from_datadict( data, files, name + '_key_%s' % i ) value = self.data_widget.value_from_datadict( data, files, name + '_value_%s' % i ) if key not in EMPTY_VALUES: ret.update(((key, value), )) i = i + 1 return ret def _get_media(self): """ Media for a multiwidget is the combination of all media of the subwidgets. """ media = super(MapWidget, self)._get_media() media = media + self.key_widget.media return media media = property(_get_media) def __deepcopy__(self, memo): obj = super(MapWidget, self).__deepcopy__(memo) obj.key_widget = copy.deepcopy(self.key_widget) return obj
class MapWidget(Widget): """ A widget that is composed of multiple widgets. Its render() method is different than other widgets', because it has to figure out how to split a single value for display in multiple widgets. The ``value`` argument can be one of two things: * A list. * A normal value (e.g., a string) that has been "compressed" from a list of values. In the second case -- i.e., if the value is NOT a list -- render() will first "decompress" the value into a list before rendering it. It does so by calling the decompress() method, which MultiWidget subclasses must implement. This method takes a single "compressed" value and returns a list. When render() does its HTML rendering, each value in the list is rendered with the corresponding widget -- the first value is rendered in the first widget, the second value is rendered in the second widget, etc. Subclasses may implement format_output(), which takes the list of rendered widgets and returns a string of HTML that formats them any way you'd like. You'll probably want to use this class with MultiValueField. """ def __init__(self, widget_type, attrs=None): self.widget_type = widget_type self.key_widget = TextInput() self.key_widget.is_localized = self.is_localized self.data_widget = self.widget_type() self.data_widget.is_localized = self.is_localized super(MapWidget, self).__init__(attrs) def render(self, name, value, attrs=None): if value is not None and not isinstance(value, dict): raise TypeError("Value supplied for %s must be a dict." % name) output = [] final_attrs = self.build_attrs(attrs) id_ = final_attrs.get('id', None) fieldset_attr = {} value = list(value.items()) # in Python 3.X dict.items() returns dynamic *view objects* value.append(('', '')) for i, (key, widget_value) in enumerate(value): if id_: fieldset_attr = dict(final_attrs, id='fieldset_%s_%s' % (id_, i)) group = [] group.append(mark_safe('<fieldset %s>' % flatatt(fieldset_attr))) if id_: final_attrs = dict(final_attrs, id='%s_key_%s' % (id_, i)) group.append(self.key_widget.render(name + '_key_%s' % i, key, final_attrs)) if id_: final_attrs = dict(final_attrs, id='%s_value_%s' % (id_, i)) group.append(self.data_widget.render(name + '_value_%s' % i, widget_value, final_attrs)) group.append(mark_safe('</fieldset>')) output.append(mark_safe(''.join(group))) return mark_safe(self.format_output(output)) def id_for_label(self, id_): # See the comment for RadioSelect.id_for_label() if id_: id_ += '_0' return id_ def value_from_datadict(self, data, files, name): i = 0 ret = {} while (name + '_key_%s' % i) in data: key = self.key_widget.value_from_datadict(data, files, name + '_key_%s' % i) value = self.data_widget.value_from_datadict(data, files, name + '_value_%s' % i) if key not in EMPTY_VALUES: ret.update(((key, value), )) i = i + 1 return ret def format_output(self, rendered_widgets): """ Given a list of rendered widgets (as strings), returns a Unicode string representing the HTML for the whole lot. This hook allows you to format the HTML design of the widgets, if needed. """ return ''.join(rendered_widgets) def _get_media(self): "Media for a multiwidget is the combination of all media of the subwidgets" media = Media() for w in self.widgets: media = media + w.media return media media = property(_get_media) def __deepcopy__(self, memo): obj = super(MapWidget, self).__deepcopy__(memo) obj.widget_type = copy.deepcopy(self.widget_type) obj.key_widget = copy.deepcopy(self.key_widget) obj.data_widget = copy.deepcopy(self.data_widget) return obj
class MapWidget(Widget): """ A widget that is composed of multiple widgets. Its render() method is different than other widgets', because it has to figure out how to split a single value for display in multiple widgets. The ``value`` argument can be one of two things: * A list. * A normal value (e.g., a string) that has been "compressed" from a list of values. In the second case -- i.e., if the value is NOT a list -- render() will first "decompress" the value into a list before rendering it. It does so by calling the decompress() method, which MultiWidget subclasses must implement. This method takes a single "compressed" value and returns a list. When render() does its HTML rendering, each value in the list is rendered with the corresponding widget -- the first value is rendered in the first widget, the second value is rendered in the second widget, etc. Subclasses may implement format_output(), which takes the list of rendered widgets and returns a string of HTML that formats them any way you'd like. You'll probably want to use this class with MultiValueField. """ def __init__(self, contained_widget, attrs=None): self.key_widget = TextInput() self.key_widget.is_localized = self.is_localized if isinstance(contained_widget, type): contained_widget = contained_widget() self.data_widget = contained_widget self.data_widget.is_localized = self.is_localized super(MapWidget, self).__init__(attrs) def render(self, name, value, attrs=None): if value is not None and not isinstance(value, dict): raise TypeError("Value supplied for %s must be a dict." % name) output = [] final_attrs = self.build_attrs(attrs) id_ = final_attrs.get('id', None) fieldset_attr = {} value = list(value.items( )) # in Python 3.X dict.items() returns dynamic *view objects* value.append(('', '')) for i, (key, widget_value) in enumerate(value): if id_: fieldset_attr = dict(final_attrs, id='fieldset_%s_%s' % (id_, i)) group = [] group.append(mark_safe('<fieldset %s>' % flatatt(fieldset_attr))) if id_: final_attrs = dict(final_attrs, id='%s_key_%s' % (id_, i)) group.append( self.key_widget.render(name + '_key_%s' % i, key, final_attrs)) if id_: final_attrs = dict(final_attrs, id='%s_value_%s' % (id_, i)) group.append( self.data_widget.render(name + '_value_%s' % i, widget_value, final_attrs)) group.append(mark_safe('</fieldset>')) output.append(mark_safe(''.join(group))) return mark_safe(self.format_output(output)) def id_for_label(self, id_): # See the comment for RadioSelect.id_for_label() if id_: id_ += '_0' return id_ def value_from_datadict(self, data, files, name): i = 0 ret = {} while (name + '_key_%s' % i) in data: key = self.key_widget.value_from_datadict(data, files, name + '_key_%s' % i) value = self.data_widget.value_from_datadict( data, files, name + '_value_%s' % i) if key not in EMPTY_VALUES: ret.update(((key, value), )) i = i + 1 return ret def format_output(self, rendered_widgets): """ Given a list of rendered widgets (as strings), returns a Unicode string representing the HTML for the whole lot. This hook allows you to format the HTML design of the widgets, if needed. """ return ''.join(rendered_widgets) def _get_media(self): "Media for a multiwidget is the combination of all media of the subwidgets" media = Media() for w in self.widgets: media = media + w.media return media media = property(_get_media) def __deepcopy__(self, memo): obj = super(MapWidget, self).__deepcopy__(memo) obj.key_widget = copy.deepcopy(self.key_widget) obj.data_widget = copy.deepcopy(self.data_widget) return obj
class MapWidget(BaseContainerWidget): def __init__(self, data_widget, attrs=None): self.key_widget = TextInput() self.key_widget.is_localized = self.is_localized super(MapWidget, self).__init__(data_widget, attrs) def render(self, name, value, attrs=None): if value is not None and not isinstance(value, dict): raise TypeError("Value supplied for %s must be a dict." % name) output = [] final_attrs = self.build_attrs(attrs) id_ = final_attrs.get('id', None) fieldset_attr = {} # in Python 3.X dict.items() returns dynamic *view objects* value = list(value.items()) value.append(('', '')) for i, (key, widget_value) in enumerate(value): if id_: fieldset_attr = dict(final_attrs, id='fieldset_%s_%s' % (id_, i)) group = [] if not self.is_hidden: group.append( mark_safe('<fieldset %s>' % flatatt(fieldset_attr))) if id_: final_attrs = dict(final_attrs, id='%s_key_%s' % (id_, i)) group.append( self.key_widget.render(name + '_key_%s' % i, key, final_attrs)) if id_: final_attrs = dict(final_attrs, id='%s_value_%s' % (id_, i)) group.append( self.data_widget.render(name + '_value_%s' % i, widget_value, final_attrs)) if not self.is_hidden: group.append(mark_safe('</fieldset>')) output.append(mark_safe(''.join(group))) return mark_safe(self.format_output(output)) def value_from_datadict(self, data, files, name): i = 0 ret = {} while (name + '_key_%s' % i) in data: key = self.key_widget.value_from_datadict(data, files, name + '_key_%s' % i) value = self.data_widget.value_from_datadict( data, files, name + '_value_%s' % i) if key not in EMPTY_VALUES: ret.update(((key, value), )) i = i + 1 return ret def _get_media(self): """ Media for a multiwidget is the combination of all media of the subwidgets. """ media = super(MapWidget, self)._get_media() media = media + self.key_widget.media return media media = property(_get_media) def __deepcopy__(self, memo): obj = super(MapWidget, self).__deepcopy__(memo) obj.key_widget = copy.deepcopy(self.key_widget) return obj