return model.for_tenant(tenant) except Exception: logger = logging.getLogger('tenancy.pickling') logger.exception('Failed to unpickle mutable tenant model') def __pickle_mutable_tenant_model_base(model): if issubclass(model, TenantSpecificModel): tenant = getattr(model, get_tenant_model().ATTR_NAME) return ( __unpickle_mutable_tenant_model_base, (model._for_tenant_model, tenant.natural_key(), model._meta.abstract) ) return model.__name__ copyreg.pickle(MutableTenantModelBase, __pickle_mutable_tenant_model_base) @receiver(mutable_class_prepared) def contribute_to_related_mutable_class(sender, existing_model_class, **kwargs): """ Since related fields are contributing to the related class only once (on the first time `class_prepared` is triggered) we make sure they also do the same with mutated classes they relate to in order to attach objects such as reverse descriptor. """ if existing_model_class: related_objects = ( related_object for related_object, model in sender._meta.get_all_related_objects_with_model() if model is None )
except Exception: logger = logging.getLogger('tenancy.pickling') logger.exception('Failed to unpickle mutable tenant model') def __pickle_mutable_tenant_model_base(model): if issubclass(model, TenantSpecificModel): tenant = getattr(model, get_tenant_model().ATTR_NAME) return ( __unpickle_mutable_tenant_model_base, (model._for_tenant_model, tenant.natural_key(), model._meta.abstract) ) return model.__name__ copyreg.pickle(MutableTenantModelBase, __pickle_mutable_tenant_model_base) @receiver(mutable_class_prepared) def contribute_to_related_mutable_class(sender, existing_model_class, **kwargs): """ Since related fields are contributing to the related class only once (on the first time `class_prepared` is triggered) we make sure they also do the same with mutated classes they relate to in order to attach objects such as reverse descriptor. """ tenant_attr_name = get_tenant_model().ATTR_NAME try: tenant = getattr(sender, tenant_attr_name) except AttributeError: pass
except Exception: logger = logging.getLogger('tenancy.pickling') logger.exception('Failed to unpickle tenant model') def __pickle_tenant_model_base(model): if issubclass(model, TenantSpecificModel): tenant = getattr(model, get_tenant_model().ATTR_NAME) return ( __unpickle_tenant_model_base, (model._for_tenant_model, tenant.natural_key(), model._meta.abstract) ) return model.__name__ copyreg.pickle(TenantModelBase, __pickle_tenant_model_base) class TenantModelDescriptor(object): __slots__ = ['model'] def __init__(self, model): self.model = model def __get__(self, tenant, owner): if not tenant: return self return tenant.models[self.model]._default_manager class TenantModel(with_metaclass(TenantModelBase, models.Model)):