Ejemplo n.º 1
0
class CompositeField(Field):
    """ Composit field """

    fields = None
    tmpl_input = 'form:composite'
    tmpl_widget = 'form:widget-composite'

    inline = False
    consolidate_errors = False

    def __init__(self, *args, **kw):
        super(CompositeField, self).__init__(*args, **kw)

        if not self.fields:
            raise ValueError('Fields are required for composite field.')

        if not isinstance(self.fields, Fieldset):
            self.fields = Fieldset(*self.fields)

        self.fields.prefix = '%s.'%self.name

    @reify
    def default(self):
        return dict(
            [(name,
              field.default if field.default is not null else field.missing)
             for name, field in self.fields.items()])

    def bind(self, request, prefix, value, params, context=None):
        """ Bind field to value and request params """
        if value in (null, None):
            value = {}

        clone = super(CompositeField, self).bind(
            request, prefix, value, params, context)

        clone.fields = self.fields.bind(request, value, params, '', context)
        return clone

    def set_id_prefix(self, prefix):
        self.id = ('%s%s'%(prefix, self.name)).replace('.', '-')

        prefix = '%s%s.'%(prefix, self.name)

        for name, field in self.fields.items():
            field.set_id_prefix(prefix)

    def update(self):
        """ Update field, prepare field for rendering """
        super(CompositeField, self).update()

        for field in self.fields.values():
            field.update()

    def to_field(self, value):
        """ convert form value to field value """
        result = {}
        errors = []
        for name, val in value.items():
            field = self.fields[name]
            try:
                result[name] = field.to_field(val)
            except Invalid as error:
                error.name = name
                errors.append(error)
                if field.error is None:
                    field.error = error

        if errors:
            if self.consolidate_errors:
                raise CompositeError(errors[0].msg, field=self)
            else:
                raise CompositeError(field=self, errors=errors)

        return result

    def validate(self, value):
        """ validate value """
        errors = []
        for name, val in value.items():
            field = self.fields[name]
            try:
                field.validate(val)
            except Invalid as error:
                error.name = name
                errors.append(error)
                if field.error is None:
                    field.error = error

        if errors:
            if self.consolidate_errors:
                raise CompositeError(errors[0].msg, field=self)
            else:
                raise CompositeError(field=self, errors=errors)

        if self.validator is not None:
            self.validator(self, value)

    def extract(self):
        value = {}
        for name, field in self.fields.items():
            val = field.extract()
            if val is null and field.missing is not null:
                val = copy.copy(field.missing)

            value[name] = val

        return value

    def flatten(self, value):
        for name, field in self.fields.items():
            if field.flat and name in value:
                value.update(field.flatten(value.pop(name)))

        return value
Ejemplo n.º 2
0
class CompositeField(Field):
    """ Composit field """

    fields = None
    tmpl_input = 'form:composite'
    tmpl_widget = 'form:widget-composite'

    inline = False
    consolidate_errors = False

    def __init__(self, *args, **kw):
        super(CompositeField, self).__init__(*args, **kw)

        if not self.fields:
            raise ValueError('Fields are required for composite field.')

        if not isinstance(self.fields, Fieldset):
            self.fields = Fieldset(*self.fields)

        self.fields.prefix = '%s.' % self.name

    @reify
    def default(self):
        return dict([
            (name,
             field.default if field.default is not null else field.missing)
            for name, field in self.fields.items()
        ])

    def bind(self, request, prefix, value, params, context=None):
        """ Bind field to value and request params """
        if value in (null, None):
            value = {}

        clone = super(CompositeField, self).bind(request, prefix, value,
                                                 params, context)

        clone.fields = self.fields.bind(request, value, params, '', context)
        return clone

    def set_id_prefix(self, prefix):
        self.id = ('%s%s' % (prefix, self.name)).replace('.', '-')

        prefix = '%s%s.' % (prefix, self.name)

        for name, field in self.fields.items():
            field.set_id_prefix(prefix)

    def update(self):
        """ Update field, prepare field for rendering """
        super(CompositeField, self).update()

        for field in self.fields.values():
            field.update()

    def to_field(self, value):
        """ convert form value to field value """
        result = {}
        errors = []
        for name, val in value.items():
            field = self.fields[name]
            try:
                result[name] = field.to_field(val)
            except Invalid as error:
                error.name = name
                errors.append(error)
                if field.error is None:
                    field.error = error

        if errors:
            if self.consolidate_errors:
                raise CompositeError(errors[0].msg, field=self)
            else:
                raise CompositeError(field=self, errors=errors)

        return result

    def validate(self, value):
        """ validate value """
        errors = []
        for name, val in value.items():
            field = self.fields[name]
            try:
                field.validate(val)
            except Invalid as error:
                error.name = name
                errors.append(error)
                if field.error is None:
                    field.error = error

        if errors:
            if self.consolidate_errors:
                raise CompositeError(errors[0].msg, field=self)
            else:
                raise CompositeError(field=self, errors=errors)

        if self.validator is not None:
            self.validator(self, value)

    def extract(self):
        value = {}
        for name, field in self.fields.items():
            val = field.extract()
            if val is null and field.missing is not null:
                val = copy.copy(field.missing)

            value[name] = val

        return value

    def flatten(self, value):
        for name, field in self.fields.items():
            if field.flat and name in value:
                value.update(field.flatten(value.pop(name)))

        return value