Пример #1
0
class BaseNHDField(DField):
    ''' Parent class for NHDField. NHDField is based on value HistoryRecordList, but this field only
        switches between two fields according to history flag.
    '''
    def __init__(self, normal_field, history_field, *content, **kwd):
        self.normal_field = normal_field
        self.history_field = history_field
        self.current_field = None
        self._owner_detail = None
        self.displaying_history = False
        super(BaseNHDField, self).__init__(*content, **kwd)

    def _assign_current_field(self, new_current_field):
        self.current_field = new_current_field

    def value_from_data(self, data):
        value = data.get(self.name)
        if self.owner_detail.history:
            self._assign_current_field(self.history_field)
        else:
            self._assign_current_field(self.normal_field)
        return value

    def _set_value(self, value):
        if self.access:
            self._value = self.current_field.value = self.resolve_value(value)
            self.make_content()
        else:
            self._value = self.current_field.value = None
            self.make_content_no_access()

    def _get_value(self):
        if self.current_field:
            return self.current_field._value
        else:
            return fredtypes.Null()

    def _set_owner_detail(self, value):
        self._owner_detail = self.normal_field.owner_detail = self.history_field.owner_detail = value

    def _get_owner_detail(self):
        return self._owner_detail

    owner_detail = LateBindingProperty(_get_owner_detail, _set_owner_detail)

    def on_add(self):
        super(BaseNHDField, self).on_add()
        if self.current_field:
            self.current_field.parent_widget = self.parent_widget
            self.current_field.on_add()

    def make_content(self):
        if self.access:
            self.content = []
            self.add(self.current_field)
Пример #2
0
class DField(WebWidget):
    ''' Base class for detail fields '''
    creation_counter = 0

    def __init__(self, name='', label=None, nperm=None, *content, **kwd):
        super(DField, self).__init__(*content, **kwd)
        self.tag = ''
        self.name = name
        self.label = label
        self._nperm = nperm
        self.owner_form = None
        self._value = fredtypes.Null()  #None
        self.access = True  # if user have nperm for this field, then this will be set to False in Detail.build_fields()
        self.no_access_content = div(attr(cssc='no_access'), _('CENSORED'))

        # Increase the creation counter, and save our local copy.
        self.creation_counter = DField.creation_counter
        DField.creation_counter += 1

    def on_add(self):
        if not self.access and self.parent_widget:
            self.parent_widget.style = 'background-color: gray;'

    def make_content(self):
        self.content = []
        if self._value == '' or self._value == fredtypes.Null():
            self.add(div(attr(cssc='field_empty')))
        else:
            self.add(self._value)

    def make_content_no_access(self):
        self.content = []
        self.add(self.no_access_content)

    def resolve_value(self, value):
        if value is None:
            return fredtypes.Null()
        else:
            return value

    def _set_value(self, value):
        if self.access:
            self._value = self.resolve_value(value)
            self.make_content()
        else:
            self._value = fredtypes.Null()  #None
            self.make_content_no_access()

    def _get_value(self):
        return self._value

    value = LateBindingProperty(_get_value, _set_value)

    def value_from_data(self, data):
        if data.get(self.name) is None:
            return fredtypes.Null()
        else:
            return data.get(self.name)

    def render(self, indent_level=0):
        return super(DField, self).render(indent_level)

    def get_nperm(self):
        if self._nperm:
            return self._nperm.lower()
        else:
            return self.name.lower()
Пример #3
0
    def _get_changed_data(self):
        if self._changed_data is None:
            self._changed_data = []
            # XXX: For now we're asking the individual widgets whether or not the
            # data has changed. It would probably be more efficient to hash the
            # initial data, store it in a hidden field, and compare a hash of the
            # submitted data, but we'd need a way to easily get the string value
            # for a given field. Right now, that logic is embedded in the render
            # method of each widget.
            for name, field in self.fields.items():
                data_value = field.value_from_datadict(self.data)
                initial_value = self.initial.get(name, field.initial)
                if field._has_changed(initial_value, data_value):
                    self._changed_data.append(name)
        return self._changed_data
    changed_data = LateBindingProperty(_get_changed_data)

    def reset(self):
        """Return this form to the state it was in before data was passed to it."""
        self.data = {}
        self.is_bound = False
        self._errors = None

    def is_multipart(self):
        """
        Returns True if the form needs to be multipart-encrypted, i.e. it has
        FileInput. Otherwise, False.
        """
        for field in self.fields.values():
            if field.widget.needs_multipart_form:
                return True
Пример #4
0
class MultiValueField(Field):
    """
    A Field that aggregates the logic of multiple Fields.

    Its clean() method takes a "decompressed" list of values, which are then
    cleaned into a single value according to self.fields. Each value in
    this list is cleaned by the corresponding field -- the first value is
    cleaned by the first field, the second value is cleaned by the second
    field, etc. Once all fields are cleaned, the list of clean values is
    "compressed" into a single value.

    Subclasses should not have to implement clean(). Instead, they must
    implement compress(), which takes a list of valid values and returns a
    "compressed" version of those values -- a single value.

    """
    tattr_list = span.tattr_list

    def __init__(self, name='', value='', fields=None, *args, **kwargs):

        # Set 'required' to False on the individual fields, because the
        # required validation will be handled by MultiValueField, not by those
        # individual fields.
        if fields is None:
            fields = []
        for field in fields:
            field.required = False
        self.fields = fields
        self._name = ''
        super(MultiValueField, self).__init__(name, value, *args, **kwargs)
        self.tag = 'span'
        self.enclose_content = True

    def _set_name(self, value):
        self._name = value
        for i, field in enumerate(self.fields):
            field.name = self._name + '/%d' % i

    def _get_name(self):
        return self._name

    name = property(_get_name, _set_name)

    def _set_value(self, value):
        if not value:
            self._value = [None] * len(self.fields)
            for field in self.fields:
                field.value = None
        else:
            self._value = value
            if not isiterable(value) and len(value) != len(self.fields):
                raise TypeError(
                    u'value of MultiValueField must be sequence with the same length as a number of fields in multifield (was % s)'
                    % unicode(value))
            for i, val in enumerate(value):
                self.fields[i].value = val

    def _get_value(self):
        return self._value

    value = LateBindingProperty(_get_value, _set_value)

    def make_content(self):
        self.content = []
        for field in self.fields:
            label_str = field.label or ''
            if label_str:
                label_str += ':'
            self.add(label_str, field)

    def render(self, indent_level=0):
        self.make_content()
        return super(MultiValueField, self).render(indent_level)

    def clean(self):
        """
        Validates every value of self.fields.

        For example, if this MultiValueField was instantiated with
        fields=(DateField(), TimeField()), clean() would call
        DateField.clean() and TimeField.clean().
        """
        clean_data = []
        errors = ErrorList()

        for field in self.fields:
            if self.required and field.required and field.is_empty():
                raise ValidationError(_(u'This field is required.'))
            try:
                clean_data.append(field.clean())
            except ValidationError, e:
                # Collect all validation errors in a single list, which we'll
                # raise at the end of clean(), rather than raising a single
                # exception for the first error we encounter.
                errors.extend(e.messages)
        if errors:
            raise ValidationError(errors)
        return self.compress(clean_data)
Пример #5
0
    def _get_changed_data(self):
        if self._changed_data is None:
            self._changed_data = []
            # XXX: For now we're asking the individual widgets whether or not the
            # data has changed. It would probably be more efficient to hash the
            # initial data, store it in a hidden field, and compare a hash of the
            # submitted data, but we'd need a way to easily get the string value
            # for a given field. Right now, that logic is embedded in the render
            # method of each widget.
            for name, field in self.fields.items():
                data_value = field.value_from_datadict(self.data)
                initial_value = self.initial.get(name, field.initial)
                if field._has_changed(initial_value, data_value):
                    self._changed_data.append(name)
        return self._changed_data
    changed_data = LateBindingProperty(_get_changed_data)
    
    def reset(self):
        """Return this form to the state it was in before data was passed to it."""
        self.data = {}
        self.is_bound = False
        self._errors = None

    def is_multipart(self):
        """
        Returns True if the form needs to be multipart-encrypted, i.e. it has
        FileInput. Otherwise, False.
        """
        for field in self.fields.values():
            if field.widget.needs_multipart_form:
                return True