Пример #1
0
    def handle_field(field, subdoc, base):
        ftype = type(field).__name__

        if ftype == 'ListField' or ftype == 'SortedListField':
            child_doc = getattr(subdoc, '_form_subdocuments', {}).get(None)

            if child_doc:
                handle_field(field.field, child_doc, base)
        elif ftype == 'EmbeddedDocumentField':
            result = {}

            ajax_refs = getattr(subdoc, 'form_ajax_refs', {})

            for field_name, opts in iteritems(ajax_refs):
                child_name = make_name(base, field_name)

                if isinstance(opts, dict):
                    loader = create_ajax_loader(field.document_type_obj, child_name, field_name, opts)
                else:
                    loader = opts

                result[field_name] = loader
                references[child_name] = loader

            subdoc._form_ajax_refs = result

            child_doc = getattr(subdoc, '_form_subdocuments', None)
            if child_doc:
                handle_subdoc(field.document_type_obj, subdoc, base)
        else:
            raise ValueError('Failed to process subdocument field %s' % (field,))
Пример #2
0
def wrap_fields_in_fieldlist(form_base_class, form_class, CustomFieldList):
    """
        Create a form class with all the fields wrapped in a FieldList.

        Wrapping each field in FieldList allows submitting POST requests
        in this format: ('<field_name>-<primary_key>', '<value>')

        Used in the editable list view.

        :param form_base_class:
            WTForms form class, by default `form_base_class` from base.
        :param form_class:
            WTForms form class generated by `form.get_form`.
        :param CustomFieldList:
            WTForms FieldList class.
            By default, `CustomFieldList` is `ListEditableFieldList`.
    """
    class FieldListForm(form_base_class):
        pass

    # iterate FormMeta to get unbound fields
    for name, obj in iteritems(form_class.__dict__):
        if isinstance(obj, UnboundField):
            # wrap field in a WTForms FieldList
            setattr(FieldListForm, name, CustomFieldList(obj))

    return FieldListForm
Пример #3
0
    def __init__(
        self,
        model,
        data=None,
        name=None,
        category=None,
        endpoint=None,
        url=None,
        **kwargs
    ):
        # Allow to set any attributes from parameters
        for k, v in iteritems(kwargs):
            setattr(self, k, v)

        super(MockModelView, self).__init__(model, name, category, endpoint, url)

        self.created_models = []
        self.updated_models = []
        self.deleted_models = []

        self.search_arguments = []

        if data is None:
            self.all_models = {1: Model(1), 2: Model(2)}
        else:
            self.all_models = data

        self.last_id = len(self.all_models) + 1
Пример #4
0
    def handle_field(field, subdoc, base):
        ftype = type(field).__name__

        if ftype == 'ListField' or ftype == 'SortedListField':
            child_doc = getattr(subdoc, '_form_subdocuments', {}).get(None)

            if child_doc:
                handle_field(field.field, child_doc, base)
        elif ftype == 'EmbeddedDocumentField':
            result = {}

            ajax_refs = getattr(subdoc, 'form_ajax_refs', {})

            for field_name, opts in iteritems(ajax_refs):
                child_name = make_name(base, field_name)

                if isinstance(opts, dict):
                    loader = create_ajax_loader(field.document_type_obj, child_name, field_name, opts)
                else:
                    loader = opts

                result[field_name] = loader
                references[child_name] = loader

            subdoc._form_ajax_refs = result

            child_doc = getattr(subdoc, '_form_subdocuments', None)
            if child_doc:
                handle_subdoc(field.document_type_obj, subdoc, base)
        else:
            raise ValueError('Failed to process subdocument field %s' % (field,))
Пример #5
0
def create_editable_list_form(form_base_class, form_class, widget=None):
    """
        Create a form class with all the fields wrapped in a FieldList.

        Wrapping each field in FieldList allows submitting POST requests
        in this format: ('<field_name>-<primary_key>', '<value>')

        Used in the editable list view.

        :param form_base_class:
            WTForms form class, by default `form_base_class` from base.
        :param form_class:
            WTForms form class generated by `form.get_form`.
        :param widget:
            WTForms widget class. Defaults to `XEditableWidget`.
    """
    if widget is None:
        widget = XEditableWidget()

    class ListForm(form_base_class):
        list_form_pk = HiddenField(validators=[InputRequired()])

    # iterate FormMeta to get unbound fields, replace widget, copy to ListForm
    for name, obj in iteritems(form_class.__dict__):
        if isinstance(obj, UnboundField):
            obj.kwargs['widget'] = widget
            setattr(ListForm, name, obj)

            if name == "list_form_pk":
                raise Exception('Form already has a list_form_pk column.')

    return ListForm
Пример #6
0
def get_form(
    model,
    converter,
    base_class=form.BaseForm,
    only=None,
    exclude=None,
    field_args=None,
    allow_pk=False,
    extra_fields=None,
):
    """
        Create form from peewee model and contribute extra fields, if necessary
    """
    result = model_form(
        model,
        base_class=base_class,
        only=only,
        exclude=exclude,
        field_args=field_args,
        allow_pk=allow_pk,
        converter=converter,
    )

    if extra_fields:
        for name, field in iteritems(extra_fields):
            setattr(result, name, form.recreate_field(field))

    return result
Пример #7
0
    def populate_obj(self, model, field_name):
        inline_model = getattr(model, field_name, None)
        is_created = False
        form_is_empty = True

        if not inline_model:
            is_created = True
            inline_model = self.model()

        # iterate all inline form fields and fill model
        for name, field in iteritems(self.form._fields):
            if name != self._pk:
                field.populate_obj(inline_model, name)

            if form_is_empty and not self._looks_empty(field.data):
                form_is_empty = False

        # don't create inline model if perhaps one field was not filled
        if form_is_empty:
            return

        # set for our model updated inline model
        setattr(model, field_name, inline_model)

        # save results
        self.inline_view.on_model_change(self.form, model, is_created)
Пример #8
0
def create_editable_list_form(form_base_class, form_class, widget=None):
    """
        Create a form class with all the fields wrapped in a FieldList.

        Wrapping each field in FieldList allows submitting POST requests
        in this format: ('<field_name>-<primary_key>', '<value>')

        Used in the editable list view.

        :param form_base_class:
            WTForms form class, by default `form_base_class` from base.
        :param form_class:
            WTForms form class generated by `form.get_form`.
        :param widget:
            WTForms widget class. Defaults to `XEditableWidget`.
    """
    if widget is None:
        widget = XEditableWidget()

    class ListForm(form_base_class):
        list_form_pk = HiddenField(validators=[InputRequired()])

    # iterate FormMeta to get unbound fields, replace widget, copy to ListForm
    for name, obj in iteritems(form_class.__dict__):
        if isinstance(obj, UnboundField):
            obj.kwargs['widget'] = widget
            setattr(ListForm, name, obj)

            if name == "list_form_pk":
                raise Exception('Form already has a list_form_pk column.')

    return ListForm
Пример #9
0
 def process(self, formdata, data=unset_value):
     """ SQLAlchemy returns a dict for HSTORE columns, but WTForms cannot
         process a dict. This overrides `process` to convert the dict
         returned by SQLAlchemy to a list of classes before processing. """
     if isinstance(data, dict):
         data = [KeyValue(k, v) for k, v in iteritems(data)]
     super(InlineHstoreList, self).process(formdata, data)
Пример #10
0
Файл: app.py Проект: tensts/n6
 def populate_obj(self, obj, name):
     string_pk_models = getattr(self, 'string_pk_models', None)
     check_for_pk = True
     if string_pk_models and any([x for x in string_pk_models if isinstance(obj, x)]):
         check_for_pk = False
     for name, field in iteritems(self.form._fields):
         if not check_for_pk or name != self._pk:
             field.populate_obj(obj, name)
Пример #11
0
    def __init__(self, model, session,
                 name=None, category=None, endpoint=None, url=None,
                 **kwargs):
        for k, v in iteritems(kwargs):
            setattr(self, k, v)

        super(CustomModelView, self).__init__(model, session, name, category,
                                              endpoint, url)
Пример #12
0
    def __init__(self, model,
                 name=None, category=None, endpoint=None, url=None,
                 **kwargs):
        for k, v in iteritems(kwargs):
            setattr(self, k, v)

        super(CustomModelView, self).__init__(model,
                                              name, category,
                                              endpoint, url)
Пример #13
0
    def handle_subdoc(model, subdoc, base):
        documents = getattr(subdoc, '_form_subdocuments', {})

        for name, doc in iteritems(documents):
            field = getattr(model, name, None)

            if not field:
                raise ValueError('Invalid subdocument field %s.%s' % (model, name))

            handle_field(field, doc, make_name(base, name))
Пример #14
0
    def handle_subdoc(model, subdoc, base):
        documents = getattr(subdoc, '_form_subdocuments', {})

        for name, doc in iteritems(documents):
            field = getattr(model, name, None)

            if not field:
                raise ValueError('Invalid subdocument field %s.%s' % (model, name))

            handle_field(field, doc, make_name(base, name))
Пример #15
0
 def get_list_form(self):
     if self.form_args:
         validators = dict((key, {
             'validators': value["validators"]
         }) for key, value in iteritems(self.form_args)
                           if value.get("validators"))
     else:
         validators = None
     return self.scaffold_list_form(
         ToggleInlineWidget(self.column_toggle_control_list,
                            self.toggle_control_options), validators)
Пример #16
0
    def _get_model_fields(self, model=None):
        """
            Inspect model and return list of model fields

            :param model:
                Model to inspect
        """
        if model is None:
            model = self.model

        return sorted(iteritems(model._fields), key=lambda n: n[1].creation_counter)
Пример #17
0
    def _get_model_fields(self, model=None):
        """
            Inspect model and return list of model fields

            :param model:
                Model to inspect
        """
        if model is None:
            model = self.model

        return sorted(iteritems(model._fields), key=lambda n: n[1].creation_counter)
Пример #18
0
    def handle_subdoc(model, subdoc, base):
        documents = getattr(subdoc, "_form_subdocuments", {})

        for name, doc in iteritems(documents):
            if name.endswith("__field"):
                name = name[:-7]
            field = getattr(model, name, None)

            if not field:
                raise ValueError("Invalid subdocument field %s.%s" % (model, name))

            handle_field(field, doc, make_name(base, name))
Пример #19
0
def convert_subdocuments(values):
    result = {}

    for name, p in iteritems(values):
        if isinstance(p, dict):
            result[name] = EmbeddedForm(**p)
        elif isinstance(p, EmbeddedForm):
            result[name] = p
        else:
            raise ValueError('Invalid subdocument type: expecting dict or instance of flask_admin.contrib.mongoengine.EmbeddedForm, got %s' % type(p))

    return result
Пример #20
0
def convert_subdocuments(values):
    result = {}

    for name, p in iteritems(values):
        if isinstance(p, dict):
            result[name] = EmbeddedForm(**p)
        elif isinstance(p, EmbeddedForm):
            result[name] = p
        else:
            raise ValueError(
                'Invalid subdocument type: expecting dict or instance of flask_admin.contrib.mongoengine.EmbeddedForm, got %s'
                % type(p))

    return result
Пример #21
0
    def process_ajax_refs(self, info):
        refs = getattr(info, 'form_ajax_refs', None)

        result = {}

        if refs:
            for name, opts in iteritems(refs):
                loader = None
                if isinstance(opts, dict):
                    loader = create_ajax_loader(info.model, name, name, opts)
                else:
                    loader = opts

                result[name] = loader
                self.view._form_ajax_refs[name] = loader

        return result
Пример #22
0
    def __init__(self, model, name=None, category=None, endpoint=None, url=None,
                 **kwargs):
        # Allow to set any attributes from parameters
        for k, v in iteritems(kwargs):
            setattr(self, k, v)

        super(MockModelView, self).__init__(model, name, category, endpoint, url)

        self.created_models = []
        self.updated_models = []
        self.deleted_models = []

        self.search_arguments = []

        self.all_models = {1: Model(1),
                           2: Model(2)}
        self.last_id = 3
Пример #23
0
    def process_ajax_refs(self, info):
        refs = getattr(info, 'form_ajax_refs', None)

        result = {}

        if refs:
            for name, opts in iteritems(refs):
                loader = None
                if isinstance(opts, dict):
                    loader = create_ajax_loader(info.model, name, name, opts)
                else:
                    loader = opts

                result[name] = loader
                self.view._form_ajax_refs[name] = loader

        return result
Пример #24
0
    def process_ajax_refs(self, info):
        refs = getattr(info, 'form_ajax_refs', None)

        result = {}

        if refs:
            for name, opts in iteritems(refs):
                new_name = '%s.%s' % (info.model.__name__.lower(), name)

                loader = None
                if isinstance(opts, (list, tuple)):
                    loader = create_ajax_loader(info.model, new_name, name, opts)
                else:
                    loader = opts

                result[name] = loader
                self.view._form_ajax_refs[new_name] = loader

        return result
Пример #25
0
def get_form(model, converter,
             base_class=form.BaseForm,
             only=None,
             exclude=None,
             field_args=None,
             extra_fields=None):

    field_args = field_args or {}

    # Find properties
    properties = sorted(((v.name, v) for v in model._meta.fields))

    if only:
        props = dict(properties)

        def find(name):
            if extra_fields and name in extra_fields:
                return FieldPlaceholder(extra_fields[name])

            p = props.get(name)
            if p is not None:
                return p

            raise ValueError('Invalid model property name %s.%s' % (model, name))

        properties = ((p, find(p)) for p in only)
    elif exclude:
        properties = (p for p in properties if p[0] not in exclude)

    # Create fields
    field_dict = {}
    for name, p in properties:
        field = converter.convert(model, p, field_args.get(name))
        if field is not None:
            field_dict[name] = field

    # Contribute extra fields
    if not only and extra_fields:
        for name, field in iteritems(extra_fields):
            field_dict[name] = form.recreate_field(field)

    field_dict['model_class'] = model
    return type(model.__name__ + 'Form', (base_class,), field_dict)
Пример #26
0
    def process_ajax_refs(self, info):
        refs = getattr(info, 'form_ajax_refs', None)

        result = {}

        if refs:
            for name, opts in iteritems(refs):
                new_name = '%s-%s' % (info.model.__name__.lower(), name)

                loader = None
                if isinstance(opts, dict):
                    loader = create_ajax_loader(info.model, self.session, new_name, name, opts)
                else:
                    loader = opts

                result[name] = loader
                self.view._form_ajax_refs[new_name] = loader

        return result
Пример #27
0
    def process_ajax_refs(self, info):
        refs = getattr(info, "form_ajax_refs", None)

        result = {}

        if refs:
            for name, opts in iteritems(refs):
                new_name = "%s-%s" % (info.model.__name__.lower(), name)

                loader = None
                if isinstance(opts, dict):
                    loader = create_ajax_loader(info.model, self.session,
                                                new_name, name, opts)
                else:
                    loader = opts

                result[name] = loader
                self.view._form_ajax_refs[new_name] = loader

        return result
Пример #28
0
def enum_create_editable_list_form(form_base_class, form_class, widget=None):
    if widget is None:
        widget = EnumEnabledXEditableWidget()  # Modification

    class ListForm(form_base_class):
        list_form_pk = HiddenField(validators=[InputRequired()])

    # iterate FormMeta to get unbound fields, replace widget, copy to ListForm
    for name, obj in iteritems(form_class.__dict__):

        if isinstance(obj, UnboundField):
            if name == 'status':  # Modification
                obj.kwargs['widget'] = StatusEnumEnabledXEditableWidget()
            else:
                obj.kwargs['widget'] = widget
            setattr(ListForm, name, obj)

            if name == "list_form_pk":
                raise Exception('Form already has a list_form_pk column.')

    return ListForm
Пример #29
0
    def __init__(self, **kwargs):
        """
            Constructor

            :param kwargs:
                Additional options
        """
        for k in self._defaults:
            if not hasattr(self, k):
                setattr(self, k, None)

        for k, v in iteritems(kwargs):
            setattr(self, k, v)

        # Convert form rules
        form_rules = getattr(self, 'form_rules', None)

        if form_rules:
            self._form_rules = rules.RuleSet(self, form_rules)
        else:
            self._form_rules = None
Пример #30
0
def get_form(model, converter,
             base_class=form.BaseForm,
             only=None,
             exclude=None,
             field_args=None,
             allow_pk=False,
             extra_fields=None):
    """
        Create form from peewee model and contribute extra fields, if necessary
    """
    result = model_form(model,
                        base_class=base_class,
                        only=only,
                        exclude=exclude,
                        field_args=field_args,
                        allow_pk=allow_pk,
                        converter=converter)

    if extra_fields:
        for name, field in iteritems(extra_fields):
            setattr(result, name, form.recreate_field(field))

    return result
Пример #31
0
def get_form(model,
             converter,
             base_class=form.BaseForm,
             only=None,
             exclude=None,
             field_args=None,
             hidden_pk=False,
             ignore_hidden=True,
             extra_fields=None):
    """
        Generate form from the model.

        :param model:
            Model to generate form from
        :param converter:
            Converter class to use
        :param base_class:
            Base form class
        :param only:
            Include fields
        :param exclude:
            Exclude fields
        :param field_args:
            Dictionary with additional field arguments
        :param hidden_pk:
            Generate hidden field with model primary key or not
        :param ignore_hidden:
            If set to True (default), will ignore properties that start with underscore
    """

    # TODO: Support new 0.8 API
    if not hasattr(model, '_sa_class_manager'):
        raise TypeError('model must be a sqlalchemy mapped model')

    mapper = model._sa_class_manager.mapper
    field_args = field_args or {}

    properties = ((p.key, p) for p in mapper.iterate_properties)

    if only:

        def find(name):
            # If field is in extra_fields, it has higher priority
            if extra_fields and name in extra_fields:
                return name, FieldPlaceholder(extra_fields[name])

            column, path = get_field_with_path(model,
                                               name,
                                               return_remote_proxy_attr=False)

            if path and not (is_relationship(column)
                             or is_association_proxy(column)):
                raise Exception("form column is located in another table and "
                                "requires inline_models: {0}".format(name))

            if is_association_proxy(column):
                return name, column

            relation_name = column.key

            if column is not None and hasattr(column, 'property'):
                return relation_name, column.property

            raise ValueError('Invalid model property name %s.%s' %
                             (model, name))

        # Filter properties while maintaining property order in 'only' list
        properties = (find(x) for x in only)
    elif exclude:
        properties = (x for x in properties if x[0] not in exclude)

    field_dict = {}
    for name, p in properties:
        # Ignore protected properties
        if ignore_hidden and name.startswith('_'):
            continue

        prop = _resolve_prop(p)

        field = converter.convert(model, mapper, name, prop,
                                  field_args.get(name), hidden_pk)
        if field is not None:
            field_dict[name] = field

    # Contribute extra fields
    if not only and extra_fields:
        for name, field in iteritems(extra_fields):
            field_dict[name] = form.recreate_field(field)

    return type(model.__name__ + 'Form', (base_class, ), field_dict)
Пример #32
0
 def populate_obj(self, obj, name):
     for name, field in iteritems(self.form._fields):
         if field.type != self.hidden_field_type:
             field.populate_obj(obj, name)
Пример #33
0
def get_form(
    model,
    converter,
    base_class=form.BaseForm,
    only=None,
    exclude=None,
    field_args=None,
    hidden_pk=False,
    ignore_hidden=True,
    extra_fields=None,
):
    """
        Generate form from the model.

        :param model:
            Model to generate form from
        :param converter:
            Converter class to use
        :param base_class:
            Base form class
        :param only:
            Include fields
        :param exclude:
            Exclude fields
        :param field_args:
            Dictionary with additional field arguments
        :param hidden_pk:
            Generate hidden field with model primary key or not
        :param ignore_hidden:
            If set to True (default), will ignore properties that start with underscore
    """

    # TODO: Support new 0.8 API
    if not hasattr(model, "_sa_class_manager"):
        raise TypeError("model must be a sqlalchemy mapped model")

    mapper = model._sa_class_manager.mapper
    field_args = field_args or {}

    properties = ((p.key, p) for p in mapper.iterate_properties)

    if only:
        props = dict(properties)

        def find(name):
            # If field is in extra_fields, it has higher priority
            if extra_fields and name in extra_fields:
                return FieldPlaceholder(extra_fields[name])

            # Try to look it up in properties list first
            p = props.get(name)

            if p is not None:
                return p

            # If it is hybrid property or alias, look it up in a model itself
            p = getattr(model, name, None)
            if p is not None and hasattr(p, "property"):
                return p.property

            raise ValueError("Invalid model property name %s.%s" % (model, name))

        # Filter properties while maintaining property order in 'only' list
        properties = ((x, find(x)) for x in only)
    elif exclude:
        properties = (x for x in properties if x[0] not in exclude)

    field_dict = {}
    for name, p in properties:
        # Ignore protected properties
        if ignore_hidden and name.startswith("_"):
            continue

        prop = _resolve_prop(p)

        field = converter.convert(model, mapper, prop, field_args.get(name), hidden_pk)
        if field is not None:
            field_dict[name] = field

    # Contribute extra fields
    if not only and extra_fields:
        for name, field in iteritems(extra_fields):
            field_dict[name] = form.recreate_field(field)

    return type(model.__name__ + "Form", (base_class,), field_dict)
Пример #34
0
def get_form(model,
             base_class=form.BaseForm,
             only=None,
             exclude=None,
             field_args=None,
             extra_fields=None):
    """
    Create a wtforms Form for a given mongoengine Document schema::

        from flask_mongoengine.wtf import model_form
        from myproject.myapp.schemas import Article
        ArticleForm = model_form(Article)

    :param model:
        An RDFAlchemy class
    :param base_class:
        Base form class to extend from. Must be a ``wtforms.Form`` subclass.
    :param only:
        An optional iterable with the property names that should be included in
        the form. Only these properties will have fields.
    :param exclude:
        An optional iterable with the property names that should be excluded
        from the form. All other properties will have fields.
    :param field_args:
        An optional dictionary of field names mapping to keyword arguments used
        to construct each field object.
    :param converter:
        A converter to generate the fields based on the model properties. If
        not set, ``ModelConverter`` is used.
    """
    # if not isinstance(model, rdfalchemy.rdfSubject):
    #     raise TypeError('Model must be an RDFAlchemy rdf subject')

    field_args = field_args or {}

    # Find properties
    properties = list(model._sortable_columns.items())

    if only:
        props = dict(properties)

        def find(name):
            if extra_fields and name in extra_fields:
                return FieldPlaceholder(extra_fields[name])

            p = props.get(name)
            if p is not None:
                return p

            raise ValueError('Invalid model property name %s.%s' % (model, name))

        properties = ((p, find(p)) for p in only)

    elif exclude:
        properties = (p for p in properties if p[0] not in exclude)

    # Create fields
    field_dict = {"type":TypeField(rel=model.clResource, choice_graph=model.clResource.graph)}
    for name, p in properties:
        field = get_field(model, p, name, field_args.get(name))
        if field is not None:
            field_dict[name] = field

    # Contribute extra fields
    if not only and extra_fields:
        for name, field in iteritems(extra_fields):
            field_dict[name] = form.recreate_field(field)

    field_dict['model_class'] = model
    return type(model.__name__ + 'Form', (base_class,), field_dict)
Пример #35
0
def get_form(model,
             converter,
             base_class=form.BaseForm,
             only=None,
             exclude=None,
             field_args=None,
             hidden_pk=False,
             ignore_hidden=True,
             extra_fields=None):
    """
        Generate form from the model.

        :param model:
            Model to generate form from
        :param converter:
            Converter class to use
        :param base_class:
            Base form class
        :param only:
            Include fields
        :param exclude:
            Exclude fields
        :param field_args:
            Dictionary with additional field arguments
        :param hidden_pk:
            Generate hidden field with model primary key or not
        :param ignore_hidden:
            If set to True (default), will ignore properties that start with underscore
    """

    # TODO: Support new 0.8 API
    if not hasattr(model, '_sa_class_manager'):
        raise TypeError('model must be a sqlalchemy mapped model')

    mapper = model._sa_class_manager.mapper
    field_args = field_args or {}

    properties = ((p.key, p) for p in mapper.iterate_properties)

    if only:
        props = dict(properties)

        def find(name):
            # If field is in extra_fields, it has higher priority
            if extra_fields and name in extra_fields:
                return FieldPlaceholder(extra_fields[name])

            # Try to look it up in properties list first
            p = props.get(name)

            if p is not None:
                return p

            # If it is hybrid property or alias, look it up in a model itself
            p = getattr(model, name, None)
            if p is not None and hasattr(p, 'property'):
                return p.property

            raise ValueError('Invalid model property name %s.%s' %
                             (model, name))

        # Filter properties while maintaining property order in 'only' list
        properties = ((x, find(x)) for x in only)
    elif exclude:
        properties = (x for x in properties if x[0] not in exclude)

    field_dict = {}
    for name, p in properties:
        # Ignore protected properties
        if ignore_hidden and name.startswith('_'):
            continue

        prop = _resolve_prop(p)

        field = converter.convert(model, mapper, prop, field_args.get(name),
                                  hidden_pk)
        if field is not None:
            field_dict[name] = field

    # Contribute extra fields
    if not only and extra_fields:
        for name, field in iteritems(extra_fields):
            field_dict[name] = form.recreate_field(field)

    return type(model.__name__ + 'Form', (base_class, ), field_dict)
Пример #36
0
def get_form(model, converter,
             base_class=form.BaseForm,
             only=None,
             exclude=None,
             field_args=None,
             hidden_pk=False,
             ignore_hidden=True,
             extra_fields=None):
    """
        Generate form from the model.

        :param model:
            Model to generate form from
        :param converter:
            Converter class to use
        :param base_class:
            Base form class
        :param only:
            Include fields
        :param exclude:
            Exclude fields
        :param field_args:
            Dictionary with additional field arguments
        :param hidden_pk:
            Generate hidden field with model primary key or not
        :param ignore_hidden:
            If set to True (default), will ignore properties that start with underscore
    """

    # TODO: Support new 0.8 API
    if not hasattr(model, '_sa_class_manager'):
        raise TypeError('model must be a sqlalchemy mapped model')

    mapper = model._sa_class_manager.mapper
    field_args = field_args or {}

    properties = ((p.key, p) for p in mapper.iterate_properties)

    if only:
        def find(name):
            # If field is in extra_fields, it has higher priority
            if extra_fields and name in extra_fields:
                return name, FieldPlaceholder(extra_fields[name])

            column, path = get_field_with_path(model, name)

            if path and not hasattr(column.prop, 'direction'):
                raise Exception("form column is located in another table and "
                                "requires inline_models: {0}".format(name))

            name = column.key

            if column is not None and hasattr(column, 'property'):
                return name, column.property

            raise ValueError('Invalid model property name %s.%s' % (model, name))

        # Filter properties while maintaining property order in 'only' list
        properties = (find(x) for x in only)
    elif exclude:
        properties = (x for x in properties if x[0] not in exclude)

    field_dict = {}
    for name, p in properties:
        # Ignore protected properties
        if ignore_hidden and name.startswith('_'):
            continue

        prop = _resolve_prop(p)

        field = converter.convert(model, mapper, prop, field_args.get(name), hidden_pk)
        if field is not None:
            field_dict[name] = field

    # Contribute extra fields
    if not only and extra_fields:
        for name, field in iteritems(extra_fields):
            field_dict[name] = form.recreate_field(field)

    return type(model.__name__ + 'Form', (base_class, ), field_dict)
Пример #37
0
    def _get_model_fields(self, model=None):
        if model is None:
            model = self.model

        return iteritems(model._meta.fields)
Пример #38
0
def flash_errors(form, message):
    from flask_admin.babel import gettext
    for field_name, errors in iteritems(form.errors):
        errors = form[field_name].label.text + u": " + u", ".join(errors)
        flash(gettext(message, error=str(errors)), 'error')
Пример #39
0
 def populate_obj(self, obj, name):
     for name, field in iteritems(self.form._fields):
         if name != self._pk:
             field.populate_obj(obj, name)
Пример #40
0
def flash_errors(form, message):
    from flask_admin.babel import gettext
    for field_name, errors in iteritems(form.errors):
        errors = form[field_name].label.text + u": " + u", ".join(errors)
        flash(gettext(message, error=str(errors)), 'error')
Пример #41
0
def get_form(model, converter,
             base_class=form.BaseForm,
             only=None,
             exclude=None,
             field_args=None,
             extra_fields=None):
    """
    Create a wtforms Form for a given mongoengine Document schema::

        from flask_mongoengine.wtf import model_form
        from myproject.myapp.schemas import Article
        ArticleForm = model_form(Article)

    :param model:
        A mongoengine Document schema class
    :param base_class:
        Base form class to extend from. Must be a ``wtforms.Form`` subclass.
    :param only:
        An optional iterable with the property names that should be included in
        the form. Only these properties will have fields.
    :param exclude:
        An optional iterable with the property names that should be excluded
        from the form. All other properties will have fields.
    :param field_args:
        An optional dictionary of field names mapping to keyword arguments used
        to construct each field object.
    :param converter:
        A converter to generate the fields based on the model properties. If
        not set, ``ModelConverter`` is used.
    """

    if isinstance(model, str):
        model = get_document(model)

    if not isinstance(model, (BaseDocument, DocumentMetaclass)):
        raise TypeError('Model must be a mongoengine Document schema')

    field_args = field_args or {}

    # Find properties
    properties = sorted(((k, v) for k, v in iteritems(model._fields)),
                        key=lambda v: v[1].creation_counter)

    if only:
        props = dict(properties)

        def find(name):
            if extra_fields and name in extra_fields:
                return FieldPlaceholder(extra_fields[name])

            p = props.get(name)
            if p is not None:
                return p

            raise ValueError('Invalid model property name %s.%s' % (model, name))

        properties = ((p, find(p)) for p in only)
    elif exclude:
        properties = (p for p in properties if p[0] not in exclude)

    # Create fields
    field_dict = {}
    for name, p in properties:
        field = converter.convert(model, p, field_args.get(name))
        if field is not None:
            field_dict[name] = field

    # Contribute extra fields
    if not only and extra_fields:
        for name, field in iteritems(extra_fields):
            field_dict[name] = form.recreate_field(field)

    field_dict['model_class'] = model
    return type(model.__name__ + 'Form', (base_class,), field_dict)
Пример #42
0
    def _get_model_fields(self, model=None):
        if model is None:
            model = self.model

        return iteritems(model._meta.fields)
Пример #43
0
 def populate_obj(self, obj, name):
     for name, field in iteritems(self.form._fields):
         if name != self._pk:
             field.populate_obj(obj, name)