diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-12-02 12:40:50 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-12-02 12:40:50 -0500 |
commit | 50e3847f09580d1e322fb11f54983e9a31846f19 (patch) | |
tree | 726356a797ffc807cefb58e6c224c2e2729cc6d0 /lib/sqlalchemy/orm/util.py | |
parent | d80ee72aaa4b7f8a23e1bd55515b8446a951a5f0 (diff) | |
download | sqlalchemy-50e3847f09580d1e322fb11f54983e9a31846f19.tar.gz |
- Added new argument ``include_backrefs=True`` to the
:func:`.validates` function; when set to False, a validation event
will not be triggered if the event was initated as a backref to
an attribute operation from the other side. [ticket:1535]
- break out validation tests into an updated module test_validators
Diffstat (limited to 'lib/sqlalchemy/orm/util.py')
-rw-r--r-- | lib/sqlalchemy/orm/util.py | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py index 1b8f53c9d..b86672175 100644 --- a/lib/sqlalchemy/orm/util.py +++ b/lib/sqlalchemy/orm/util.py @@ -70,24 +70,43 @@ class CascadeOptions(frozenset): ) -def _validator_events(desc, key, validator, include_removes): +def _validator_events(desc, key, validator, include_removes, include_backrefs): """Runs a validation method on an attribute value to be set or appended.""" + if not include_backrefs: + def detect_is_backref(state, initiator): + impl = state.manager[key].impl + return initiator.impl is not impl + if include_removes: def append(state, value, initiator): - return validator(state.obj(), key, value, False) + if include_backrefs or not detect_is_backref(state, initiator): + return validator(state.obj(), key, value, False) + else: + return value def set_(state, value, oldvalue, initiator): - return validator(state.obj(), key, value, False) + if include_backrefs or not detect_is_backref(state, initiator): + return validator(state.obj(), key, value, False) + else: + return value def remove(state, value, initiator): - validator(state.obj(), key, value, True) + if include_backrefs or not detect_is_backref(state, initiator): + validator(state.obj(), key, value, True) + else: def append(state, value, initiator): - return validator(state.obj(), key, value) + if include_backrefs or not detect_is_backref(state, initiator): + return validator(state.obj(), key, value) + else: + return value def set_(state, value, oldvalue, initiator): - return validator(state.obj(), key, value) + if include_backrefs or not detect_is_backref(state, initiator): + return validator(state.obj(), key, value) + else: + return value event.listen(desc, 'append', append, raw=True, retval=True) event.listen(desc, 'set', set_, raw=True, retval=True) |