def _assign_subobject_list(self, instances, accessor):
# only known case yet is Langstring.entries
if isinstance(accessor, RelationshipProperty):
if not accessor.back_populates:
# Try the brutal approach
setattr(self, accessor.key, instances)
else:
from ..lib.history_mixin import TombstonableMixin
current_instances = getattr(self, accessor.key)
missing = set(instances) - set(current_instances)
if missing:
# Maybe tombstones
missing = filter(
lambda a: not isinstance(a, TombstonableMixin) or
not a.is_tombstone, missing)
assert not missing, "what's wrong with back_populates?"
extra = set(current_instances) - set(instances)
if extra:
remote_columns = list(accessor.remote_side)
if len(accessor.remote_side) > 1:
if issubclass(accessor.mapper.class_, TombstonableMixin):
remote_columns = filter(lambda c: c.name != 'tombstone_date', remote_columns)
assert len(remote_columns) == 1
remote = remote_columns[0]
if remote.nullable:
# TODO: check update permissions on that object.
for inst in missing:
setattr(inst, remote.key, None)
else:
for inst in extra:
if not inst.user_can(
user_id, CrudPermissions.DELETE,
permissions):
raise HTTPUnauthorized(
"Cannot delete object %s", inst.uri())
else:
if isinstance(inst, TombstonableMixin):
inst.is_tombstone = True
else:
self.db.delete(inst)
elif isinstance(accessor, property):
# Note: Does not happen yet.
property.fset(self, instances)
elif isinstance(accessor, Column):
raise HTTPBadRequest(
"%s cannot have multiple values" % (accessor.key, ))
elif isinstance(accessor, AssociationProxy):
# Also never happens
current_instances = accessor.__get__(self, self.__class__)
missing = set(instances) - set(current_instances)
extra = set(current_instances) - set(instances)
for inst in missing:
accessor.add(inst)
for inst in extra:
accessor.remove(inst)
else:
assert False, "we should not get here"
评论列表
文章目录