Commits

Maciej Wiatrzyk  committed 19585f3

ext.sqlalchemy: fix according to comments of pull request #22

  • Participants
  • Parent commits 75a9ec8

Comments (0)

Files changed (2)

File wtforms/ext/sqlalchemy/orm.py

     'model_fields', 'model_form',
 )
 
+
 def converts(*args):
     def _inner(func):
         func._converter_for = frozenset(args)
         return func
     return _inner
 
-def sa_validator(model, key, validator):
-    def _sa_validator(form, field):
-        if not isinstance(form.model_instance, model):
-            raise TypeError(
-                "form.model_instance: expecting instance of %s, found %s" %
-                (model, type(form.model_instance)))
-        validator(form.model_instance, field.name, field.data,
-            form=form, field=field)
-    return _sa_validator
 
 class ModelConverterBase(object):
     def __init__(self, converters, use_mro=True, use_sa_validators=False):
         # validators will require additional 'form' and 'field' keyword
         # arguments once called by WTForms
         if self.use_sa_validators:
-            for key, validator in mapper.validators.iteritems():
-                kwargs['validators'].append(sa_validator(model, key, validator))
+            validator = mapper.validators.get(prop.key)
+            if validator is not None:
+                kwargs['validators'].append(_sa_validator(model, prop.key, validator))
 
         return converter(model=model, mapper=mapper, prop=prop, column=column,
             field_args=kwargs)
         Enable or disable usage of SQLAlchemy validators defined in `model`
         (via `validates` decorator). Using this option will allow the user to
         have common validation routines - both for model and form created for
-        the model. Using this option requires `model_instance` parameter of
-        `Form` class to be set to instance of `model` class and the SQLAlchemy
-        validators to accept additional keyword arguments: ``form`` and
-        ``field``, both initialized with ``None``, but set to concrete
-        :class:`Form` and :class:`Field` instances once called by WTForms.
-        This option is disabled by default (for backward compatibility).
+        the model. Using this option requires `obj` parameter of `Form` class
+        to be set to instance of `model` class and the SQLAlchemy validators to
+        accept additional keyword arguments: ``form`` and ``field``, both
+        initialized with ``None``, but set to concrete :class:`Form` and
+        :class:`Field` instances once called by WTForms.  This option is
+        disabled by default (for backward compatibility).
     """
     class ModelForm(base_class):
         """Sets object as form attribute."""
     field_dict = model_fields(model, db_session, only, exclude, field_args,
         converter, use_sa_validators)
     return type(type_name, (ModelForm, ), field_dict)
+
+
+### HELPERS
+
+def _sa_validator(model, key, validator):
+    def __sa_validator(form, field):
+        if not isinstance(form.obj, model):
+            raise TypeError(
+                "form.obj: expecting instance of %s, found %s" %
+                (model, type(form.obj)))
+        validator(form.obj, field.name, field.data,
+            form=form, field=field)
+    __sa_validator.func_name = validator.func_name
+    return __sa_validator

File wtforms/form.py

 
         self._prefix = prefix
         self._errors = None
-        self._model_instance = None
         self._fields = {}
+        self._obj = None
 
         if hasattr(fields, 'items'):
             fields = fields.items()
         return self._errors
 
     @property
-    def model_instance(self):
-        return self._model_instance
+    def obj(self):
+        return self._obj
 
 
 class FormMeta(type):
     """
     __metaclass__ = FormMeta
 
-    def __init__(self, formdata=None, obj=None, prefix='', model_instance=None, **kwargs):
+    def __init__(self, formdata=None, obj=None, prefix='', **kwargs):
         """
         :param formdata:
             Used to pass data coming from the enduser, usually `request.POST` or
         :param prefix:
             If provided, all fields will have their name prefixed with the
             value.
-        :param model_instance:
-            Once `formdata`, `obj` or keyword arguments are used to populate
-            fields with submited values, this parameter is used to keep
-            original "model" instance that is not yet populated with newest
-            form data. This parameter is available by form's `model_instance`
-            property and can be used by validators to trigger specific actions
-            f.e. only if field data is different than corresponding attribute
-            of `model_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
             # attributes with the same names.
             setattr(self, name, field)
 
-        self._model_instance = model_instance
+        self._obj = obj
 
         self.process(formdata, obj, **kwargs)