def process(self, formdata=None, obj=None, data=None, **kwargs): """ Take form, object data, and keyword arg input and have the fields process them. :param formdata: Used to pass data coming from the enduser, usually `request.POST` or equivalent. :param obj: If `formdata` is empty or not provided, this object is checked for attributes matching form field names, which will be used for field values. :param data: If provided, must be a dictionary of data. This is only used if `formdata` is empty or not provided and `obj` does not contain an attribute named the same as the field. :param `**kwargs`: If `formdata` is empty or not provided and `obj` does not contain an attribute named the same as a field, form will assign the value of a matching keyword argument to the field, if one exists. """ formdata = self.meta.wrap_formdata(self, formdata) if data is not None: # XXX we want to eventually process 'data' as a new entity. # Temporarily, this can simply be merged with kwargs. kwargs = dict(data, **kwargs) for name, field, in iteritems(self._fields): if obj is not None and hasattr(obj, name): field.process(formdata, getattr(obj, name)) elif name in kwargs: field.process(formdata, kwargs[name]) else: field.process(formdata)
def html_params(**kwargs): """ Generate HTML attribute syntax from inputted keyword arguments. The output value is sorted by the passed keys, to provide consistent output each time this function is called with the same parameters. Because of the frequent use of the normally reserved keywords `class` and `for`, suffixing these with an underscore will allow them to be used. In addition, the values ``True`` and ``False`` are special: * ``attr=True`` generates the HTML compact output of a boolean attribute, e.g. ``checked=True`` will generate simply ``checked`` * ``attr=`False`` will be ignored and generate no output. >>> html_params(name='text1', id='f', class_='text') 'class="text" id="f" name="text1"' >>> html_params(checked=True, readonly=False, name="text1", abc="hello") 'abc="hello" checked name="text1"' """ params = [] for k, v in sorted(iteritems(kwargs)): if k in ('class_', 'class__', 'for_'): k = k[:-1] if v is True: params.append(k) elif v is False: pass else: params.append('%s="%s"' % (text_type(k), escape(text_type(v), quote=True))) return ' '.join(params)
def populate_obj(self, obj): """ Populates the attributes of the passed `obj` with data from the form's fields. :note: This is a destructive operation; Any attribute with the same name as a field will be overridden. Use with caution. """ for name, field in iteritems(self._fields): field.populate_obj(obj, name)
def __init__(self, extra_converters=None, simple_conversions=None): converters = {} if simple_conversions is None: simple_conversions = self.DEFAULT_SIMPLE_CONVERSIONS for field_type, django_fields in iteritems(simple_conversions): converter = self.make_simple_converter(field_type) for name in django_fields: converters[name] = converter if extra_converters: converters.update(extra_converters) super(ModelConverter, self).__init__(converters)
def model_fields(model, only=None, exclude=None, field_args=None, converter=None): """ Extracts and returns a dictionary of form fields for a given ``db.Model`` class. :param model: The ``db.Model`` class to extract fields from. :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 a 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. """ converter = converter or ModelConverter() field_args = field_args or {} # Get the field names we want to include or exclude, starting with the # full list of model properties. props = model.properties() sorted_props = sorted(iteritems(props), key=lambda prop: prop[1].creation_counter) field_names = list(x[0] for x in sorted_props) if only: field_names = list(f for f in only if f in field_names) elif exclude: field_names = list(f for f in field_names if f not in exclude) # Create all fields. field_dict = {} for name in field_names: field = converter.convert(model, props[name], field_args.get(name)) if field is not None: field_dict[name] = field return field_dict
def __init__(self, formdata=None, obj=None, prefix='', data=None, meta=None, **kwargs): """ :param formdata: Used to pass data coming from the enduser, usually `request.POST` or equivalent. formdata should be some sort of request-data wrapper which can get multiple parameters from the form input, and values are unicode strings, e.g. a Werkzeug/Django/WebOb MultiDict :param obj: If `formdata` is empty or not provided, this object is checked for attributes matching form field names, which will be used for field values. :param prefix: If provided, all fields will have their name prefixed with the value. :param data: Accept a dictionary of data. This is only used if `formdata` and `obj` are not present. :param meta: If provided, this is a dictionary of values to override attributes on this form's meta instance. :param `**kwargs`: If `formdata` is empty or not provided and `obj` does not contain an attribute named the same as a field, form will assign the value of a matching keyword argument to the field, if one exists. """ meta_obj = self._wtforms_meta() if meta is not None and isinstance(meta, dict): meta_obj.update_values(meta) super(Form, self).__init__(self._unbound_fields, meta=meta_obj, prefix=prefix) for name, field in iteritems(self._fields): # Set all the fields to attributes so that they obscure the class # attributes with the same names. setattr(self, name, field) self.process(formdata, obj, data=data, **kwargs)
def validate(self, extra_validators=None): """ Validates the form by calling `validate` on each field. :param extra_validators: If provided, is a dict mapping field names to a sequence of callables which will be passed as extra validators to the field's `validate` method. Returns `True` if no errors occur. """ self._errors = None success = True for name, field in iteritems(self._fields): if extra_validators is not None and name in extra_validators: extra = extra_validators[name] else: extra = tuple() if not field.validate(self, extra): success = False return success
def errors(self): if self._errors is None: self._errors = dict((name, f.errors) for name, f in iteritems(self._fields) if f.errors) return self._errors
def data(self): return dict((name, f.data) for name, f in iteritems(self._fields))