Source code for swimlane.core.fields.base.multiselect

from sortedcontainers import SortedSet

from swimlane.core.resources.usergroup import User

from .cursor import CursorField, FieldCursor


[docs]class MultiSelectCursor(FieldCursor): """Cursor allowing setting and unsetting values on a MultiSelectField Respects parent field's validation """ def __init__(self, *args, **kwargs): super(MultiSelectCursor, self).__init__(*args, **kwargs) self._elements = filter(lambda e: e is not None, self._elements) self._elements = SortedSet(self._elements)
[docs] def select(self, element): """Add an element to the set of selected elements Proxy to internal set.add and sync field """ self._field.validate_value(element) self._elements.add(element) self._sync_field()
[docs] def deselect(self, element): """Remove an element from the set of selected elements Proxy to internal set.remove and sync field """ self._elements.remove(element) self._sync_field()
[docs]class MultiSelectField(CursorField): """Base class for fields that can be multi-selection or single-selection field""" cursor_class = MultiSelectCursor
[docs] def get_python(self): """Only return cursor instance if configured for multiselect""" if self.multiselect: return super(MultiSelectField, self).get_python() return self._get()
[docs] def get_swimlane(self): """Handle multi-select and single-select modes""" if self.multiselect: value = self._get() children = [] if value: for child in value: children.append(self.cast_to_swimlane(child)) return children return None return super(MultiSelectField, self).get_swimlane()
def _set(self, value): """Override to treat empty lists as None""" return super(MultiSelectField, self)._set(value or None)
[docs] def set_python(self, value): """Override to remove key from raw data when empty to work with server 2.16+ validation""" if self.multiselect: value = value or [] elements = [] if not isinstance( value, ( list, MultiSelectCursor, SortedSet, User, ), ): value = [value] for element in value: self.validate_value(element) elements.append(element) value = elements else: self.validate_value(value) self._set(value)
[docs] def set_swimlane(self, value): """Cast all multi-select elements to correct internal type like single-select mode""" if self.multiselect: value = value or [] children = [] for child in value: children.append(self.cast_to_python(child)) return self._set(children) return super(MultiSelectField, self).set_swimlane(value)
[docs] def for_json(self): """Handle multi-select vs single-select""" if self.multiselect: return super(MultiSelectField, self).for_json() value = self.get_python() if hasattr(value, 'for_json'): return value.for_json() return value