def handle_field(field, subdoc, base): ftype = type(field).__name__ if ftype == 'ListField': 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,))
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
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))
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)
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 pyramid_admin.contrib.mongoengine.EmbeddedForm, got %s' % type(p)) return result
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
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
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
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
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)
def flash_errors(form, message): from pyramid_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")
def populate_obj(self, obj, name): for name, field in iteritems(self.form._fields): if name != self._pk: field.populate_obj(obj, name)