コード例 #1
0
    def getInputValue(self):
        """Return converted and validated widget data.

        If there is no user input and the field is required, then a
        ``MissingInputError`` will be raised.

        If there is no user input and the field is not required, then
        the field default value will be returned.

        A ``WidgetInputError`` is raised in the case of one or more
        errors encountered, inputting, converting, or validating the data.
        """
        if self.hasInput():
            self.preserve_widgets = True
            sequence = self._type(self._generateSequence())
            if sequence != self.context.missing_value:
                # catch and set field errors to ``_error`` attribute
                try:
                    self.context.validate(sequence)
                except WidgetInputError as error:
                    self._error = error
                    raise self._error
                except ValidationError as error:
                    self._error = WidgetInputError(self.context.__name__,
                                                   self.label, error)
                    raise self._error
            elif self.context.required:
                raise MissingInputError(self.context.__name__,
                                        self.context.title)
            return sequence
        raise MissingInputError(self.context.__name__, self.context.title)
コード例 #2
0
ファイル: widget.py プロジェクト: xhw807602352/flask_Demo
    def getInputValue(self):
        self._error = None
        field = self.context

        # form input is required, otherwise raise an error
        if not self.hasInput():
            raise MissingInputError(self.name, self.label, None)

        # convert input to suitable value - may raise conversion error
        try:
            value = self._toFieldValue(self._getFormInput())
        except ConversionError as error:
            # ConversionError is already a WidgetInputError
            self._error = error
            raise self._error

        # allow missing values only for non-required fields
        if value == field.missing_value and not field.required:
            return value

        # value must be valid per the field constraints
        try:
            field.validate(value)
        except ValidationError as v:
            self._error = WidgetInputError(self.context.__name__, self.label,
                                           v)
            raise self._error
        return value
コード例 #3
0
ファイル: widget.py プロジェクト: c0ns0le/zenoss-4
    def getInputValue(self):
        self._error = None
        field = self.context

        # form input is required, otherwise raise an error
        if not self.hasInput():
            raise MissingInputError(self.name, self.label, None)

        # convert input to suitable value - may raise conversion error
        try:
            value = self._toFieldValue(self._getFormInput())
        except ConversionError, error:
            # ConversionError is already a WidgetInputError
            self._error = error
            raise self._error
コード例 #4
0
ファイル: utility.py プロジェクト: xhw807602352/flask_Demo
def getWidgetsData(view, schema, names=None):
    """Returns user entered data for a set of `schema` fields.

    The return value is a map of field names to data values.

    `view` is the view containing the widgets. `schema` is the schema that
    defines the widget fields. An optional `names` argument can be provided
    to specify an alternate list of field values to return. If `names` is
    not specified, or is ``None``, `getWidgetsData` will attempt to return
    values for all of the fields in the schema.

    A requested field value may be omitted from the result for one of two
    reasons:

        - The field is read only, in which case its widget will not have
          user input.

        - The field is editable and not required but its widget does not
          contain user input.

    If a field is required and its widget does not have input, `getWidgetsData`
    raises an error.

    A widget may raise a validation error if it cannot return a value that
    satisfies its field's contraints.

    Errors, if any, are collected for all fields and reraised as a single
    `WidgetsError`.
    """
    result = {}
    errors = []

    for name, field in _fieldlist(names, schema):
        widget = getattr(view, name + '_widget')
        if IInputWidget.providedBy(widget):
            if widget.hasInput():
                try:
                    result[name] = widget.getInputValue()
                except InputErrors as error:
                    errors.append(error)
            elif field.required:
                errors.append(MissingInputError(
                    name, widget.label, 'the field is required'))

    if errors:
        raise WidgetsError(errors, widgetsData=result)

    return result
コード例 #5
0
    def getInputValue(self):
        for name, queryview in self.queryviews:
            if name + '.apply' in self.request:
                token = self.request.form.get(name + '.selection')
                if token is not None:
                    break
        else:
            token = self.request.get(self.name)

        field = self.context

        if token is None:
            if field.required:
                # TODO This code path is untested.
                raise MissingInputError(
                    field.__name__,
                    self.label,
                )
            return field.missing_value

        try:
            value = self.terms.getValue(str(token))
        except LookupError:
            # TODO This code path is untested.
            err = zope.schema.interfaces.ValidationError(
                "Invalid value id", token)
            raise WidgetInputError(field.__name__, self.label, err)

        # Remaining code copied from SimpleInputWidget

        # value must be valid per the field constraints
        try:
            field.validate(value)
        except ValidationError as err:
            # TODO This code path is untested.
            self._error = WidgetInputError(field.__name__, self.label, err)
            raise self._error

        return value
コード例 #6
0
    def __call__(self):
        name = self.request.form.get('name')
        if name is None:
            raise MissingInputError('name', '')

        search_text = self.request.form.get('search_text')
        if search_text is None:
            raise MissingInputError('search_text', '')
        search_filter = self.request.form.get('search_filter')

        try:
            factory = getUtility(IVocabularyFactory, name)
        except ComponentLookupError:
            raise UnexpectedFormData(
                'Unknown vocabulary %r' % name)

        vocabulary = factory(self.context)

        if IHugeVocabulary.providedBy(vocabulary):
            matches = vocabulary.searchForTerms(search_text, search_filter)
            total_size = matches.count()
        else:
            matches = list(vocabulary)
            total_size = len(matches)

        batch_navigator = BatchNavigator(matches, self.request)

        # We need to collate what IPickerEntrySource adapters are required for
        # the items in the current batch. We expect that the batch will be
        # homogenous and so only one adapter instance is required, but we
        # allow for the case where the batch may contain disparate entries
        # requiring different adapter implementations.

        # A mapping from adapter class name -> adapter instance
        adapter_cache = {}
        # A mapping from adapter class name -> list of vocab terms
        picker_entry_terms = {}
        for term in batch_navigator.currentBatch():
            picker_entry_source = IPickerEntrySource(term.value)
            adapter_class = picker_entry_source.__class__.__name__
            picker_terms = picker_entry_terms.get(adapter_class)
            if picker_terms is None:
                picker_terms = []
                picker_entry_terms[adapter_class] = picker_terms
                adapter_cache[adapter_class] = picker_entry_source
            picker_terms.append(term.value)

        # A mapping from vocab terms -> picker entries
        picker_term_entries = {}

        # For the list of terms associated with a picker adapter, we get the
        # corresponding picker entries by calling the adapter.
        for adapter_class, term_values in picker_entry_terms.items():
            picker_entries = adapter_cache[adapter_class].getPickerEntries(
                term_values,
                self.context)
            for term_value, picker_entry in izip(term_values, picker_entries):
                picker_term_entries[term_value] = picker_entry

        result = []
        for term in batch_navigator.currentBatch():
            entry = dict(value=term.token, title=term.title)
            # The canonical_url without just the path (no hostname) can
            # be passed directly into the REST PATCH call.
            api_request = IWebServiceClientRequest(self.request)
            try:
                entry['api_uri'] = canonical_url(
                    term.value, request=api_request,
                    path_only_if_possible=True)
            except NoCanonicalUrl:
                # The exception is caught, because the api_url is only
                # needed for inplace editing via a REST call. The
                # form picker doesn't need the api_url.
                entry['api_uri'] = 'Could not find canonical url.'
            picker_entry = picker_term_entries[term.value]
            if picker_entry.description is not None:
                if len(picker_entry.description) > MAX_DESCRIPTION_LENGTH:
                    entry['description'] = (
                        picker_entry.description[:MAX_DESCRIPTION_LENGTH - 3]
                        + '...')
                else:
                    entry['description'] = picker_entry.description
            if picker_entry.image is not None:
                entry['image'] = picker_entry.image
            if picker_entry.css is not None:
                entry['css'] = picker_entry.css
            if picker_entry.alt_title is not None:
                entry['alt_title'] = picker_entry.alt_title
            if picker_entry.title_link is not None:
                entry['title_link'] = picker_entry.title_link
            if picker_entry.details is not None:
                entry['details'] = picker_entry.details
            if picker_entry.alt_title_link is not None:
                entry['alt_title_link'] = picker_entry.alt_title_link
            if picker_entry.link_css is not None:
                entry['link_css'] = picker_entry.link_css
            if picker_entry.badges:
                entry['badges'] = picker_entry.badges
            if picker_entry.metadata is not None:
                entry['metadata'] = picker_entry.metadata
            if picker_entry.target_type is not None:
                entry['target_type'] = picker_entry.target_type
            result.append(entry)

        self.request.response.setHeader('Content-type', 'application/json')
        return simplejson.dumps(dict(total_size=total_size, entries=result))
コード例 #7
0
ファイル: sequencewidget.py プロジェクト: c0ns0le/zenoss-4
class SequenceWidget(BrowserWidget, InputWidget):
    """A widget baseclass for a sequence of fields.

    subwidget  - Optional CustomWidget used to generate widgets for the
                 items in the sequence
    """

    implements(IInputWidget)

    template = ViewPageTemplateFile('sequencewidget.pt')

    _type = tuple

    def __init__(self, context, field, request, subwidget=None):
        super(SequenceWidget, self).__init__(context, request)
        self.subwidget = subwidget

        # The subwidgets are cached in this dict if preserve_widgets is True.
        self._widgets = {}
        self.preserve_widgets = False

    def __call__(self):
        """Render the widget"""
        self._update()
        return self.template()

    def _update(self):
        """Set various attributes for the template"""
        sequence = self._getRenderedValue()
        num_items = len(sequence)
        self.need_add = (not self.context.max_length
                         or num_items < self.context.max_length)
        self.need_delete = num_items and num_items > self.context.min_length
        self.marker = self._getPresenceMarker(num_items)

    def widgets(self):
        """Return a list of widgets to display"""
        sequence = self._getRenderedValue()
        result = []
        for i, value in enumerate(sequence):
            widget = self._getWidget(i)
            widget.setRenderedValue(value)
            result.append(widget)
        return result

    def addButtonLabel(self):
        button_label = _('Add %s')
        button_label = translate(button_label, context=self.request,
                                 default=button_label)
        title = self.context.title or self.context.__name__
        title = translate(title, context=self.request, default=title)
        return button_label % title


    def _getWidget(self, i):
        """Return a widget for the i-th number of the sequence.

        Normally this method creates a new widget each time, but when
        the ``preserve_widgets`` attribute is True, it starts caching
        widgets.  We need it so that the errors on the subwidgets
        would appear only if ``getInputValue`` was called.

        ``getInputValue`` on the subwidgets gets called on each
        request that has data.
        """
        if i not in self._widgets:
            field = self.context.value_type
            if self.subwidget is not None:
                widget = self.subwidget(field, self.request)
            else:
                widget = component.getMultiAdapter(
                    (field, self.request), IInputWidget)
            widget.setPrefix('%s.%d.' % (self.name, i))
            if not self.preserve_widgets:
                return widget
            self._widgets[i] = widget
        return self._widgets[i]

    def hidden(self):
        """Render the list as hidden fields."""
        # length of sequence info
        sequence = self._getRenderedValue()
        num_items = len(sequence)

        # generate hidden fields for each value
        parts = [self._getPresenceMarker(num_items)]
        for i in range(num_items):
            value = sequence[i]
            widget = self._getWidget(i)
            widget.setRenderedValue(value)
            parts.append(widget.hidden())
        return "\n".join(parts)

    def _getRenderedValue(self):
        """Returns a sequence from the request or _data"""
        if self._renderedValueSet():
            if self._data is self.context.missing_value:
                sequence = []
            else:
                sequence = list(self._data)
        elif self.hasInput():
            sequence = self._generateSequence()
        elif self.context.default is not None:
            sequence = self.context.default
        else:
            sequence = []
        # ensure minimum number of items in the form
        while len(sequence) < self.context.min_length:
            # Shouldn't this use self.field.value_type.missing_value,
            # instead of None?
            sequence.append(None)
        return sequence

    def _getPresenceMarker(self, count=0):
        return ('<input type="hidden" name="%s.count" value="%d" />'
                % (self.name, count))

    def getInputValue(self):
        """Return converted and validated widget data.

        If there is no user input and the field is required, then a
        ``MissingInputError`` will be raised.

        If there is no user input and the field is not required, then
        the field default value will be returned.

        A ``WidgetInputError`` is raised in the case of one or more
        errors encountered, inputting, converting, or validating the data.
        """
        if self.hasInput():
            self.preserve_widgets = True
            sequence = self._type(self._generateSequence())
            if sequence != self.context.missing_value:
                # catch and set field errors to ``_error`` attribute
                try:
                    self.context.validate(sequence)
                except WidgetInputError, error:
                    self._error = error
                    raise self._error
                except ValidationError, error:
                    self._error = WidgetInputError(
                        self.context.__name__, self.label, error)
                    raise self._error
            elif self.context.required:
                raise MissingInputError(self.context.__name__,
                                        self.context.title)
コード例 #8
0
ファイル: sequencewidget.py プロジェクト: c0ns0le/zenoss-4
            if sequence != self.context.missing_value:
                # catch and set field errors to ``_error`` attribute
                try:
                    self.context.validate(sequence)
                except WidgetInputError, error:
                    self._error = error
                    raise self._error
                except ValidationError, error:
                    self._error = WidgetInputError(
                        self.context.__name__, self.label, error)
                    raise self._error
            elif self.context.required:
                raise MissingInputError(self.context.__name__,
                                        self.context.title)
            return sequence
        raise MissingInputError(self.context.__name__, self.context.title)

    # TODO: applyChanges isn't reporting "change" correctly (we're
    # re-generating the sequence with every edit, and need to be smarter)
    def applyChanges(self, content):
        field = self.context
        value = self.getInputValue()
        change = field.query(content, self) != value
        if change:
            field.set(content, value)
        return change

    def hasInput(self):
        """Is there input data for the field

        Return ``True`` if there is data and ``False`` otherwise.