def __init__(self, **kwargs): """ Processes the instance or instances given by the kwargs, storing instance_ids, the instance_class, and optional instance_keys, which may all be used for celery calls and client messaging :param kwargs: Currently only 'instance' is required, which is a single or list of instances. Optional arguments are: user_id: The user id of the user that instigated the save on the client instance_key: The attribute that is the key of the instance class_key: For dynamic classes, resolves the key of its scope class (e.g. 'db_entity_key' of Feature) class_path: The class path of the instance class. Defaults to the class of the first instance model_path: Backup to class_path for dynamic model resolution instance_class - Optional. Overrides the class of the instance for use in communicating with the client. This is used when the client only cares about a base class, such as Feature or for DbEntityInterest to be a DbEntity client_instance_path - Optional. Property path from the main instance to the instance to show the client (this is only used to convert DbEntityInterest to DbEntity) """ logger.debug("Creating InstanceBundle with kwargs: %s" % kwargs) self.user_id = kwargs['user_id'] self.has_keys = kwargs.get('instance_key') is not None or hasattr( kwargs['instance'], 'key') # An optional class-scope key, like the DbEntity key of Features self.class_key = kwargs.get('class_key') self.client_instance_path = kwargs.get('client_instance_path') if hasattr(kwargs['instance'], '__iter__'): self.ids = map(lambda instance: instance.id, kwargs['instance']) self.class_path = full_module_path(kwargs['instance'][0].__class__) # Backup for dynamic subclass resolution self.model_path = resolvable_model_name( kwargs['instance'][0].__class__) self.keys = map(lambda instance: kwargs.get('instance_key'), self.instances) if self.has_keys else [] else: instance = kwargs['instance'] self.ids = [instance.id] self.class_path = full_module_path(kwargs['instance'].__class__) # Backup for dynamic subclass resolution self.model_path = resolvable_model_name( kwargs['instance'].__class__) self.keys = [ kwargs['instance_key'] if kwargs.get('instance_key', None) else self.instances[0].key ] if self.has_keys else [] # Overrides the instance class of the instance for sending to the client self.override_class_path = full_module_path( kwargs['instance_class']) if kwargs.get('instance_class') else None
def pre_save(self, model_instance, add): """ Simplify the model instance to an id and class name to avoid expensive pickling """ if model_instance.id == 0: raise Exception("Attempt to pickle unsaved model instance: %s" % model_instance) simple_dict = dict(class_name=resolvable_model_name( model_instance.__class__), id=model_instance.id) return super(ModelPickledObjectField, self).pre_save(simple_dict, add)
def pre_save(self, model_instance, add): """ Simplify the model instance to an id and class name to avoid expensive pickling """ if model_instance.id == 0: raise Exception("Attempt to pickle unsaved model instance: %s" % model_instance) simple_dict = dict( class_name=resolvable_model_name(model_instance.__class__), id=model_instance.id ) return super(ModelPickledObjectField, self).pre_save(simple_dict, add)
def __init__(self, **kwargs): """ Processes the instance or instances given by the kwargs, storing instance_ids, the instance_class, and optional instance_keys, which may all be used for celery calls and client messaging :param kwargs: Currently only 'instance' is required, which is a single or list of instances. Optional arguments are: user_id: The user id of the user that instigated the save on the client instance_key: The attribute that is the key of the instance class_key: For dynamic classes, resolves the key of its scope class (e.g. 'db_entity_key' of Feature) class_path: The class path of the instance class. Defaults to the class of the first instance model_path: Backup to class_path for dynamic model resolution instance_class - Optional. Overrides the class of the instance for use in communicating with the client. This is used when the client only cares about a base class, such as Feature or for DbEntityInterest to be a DbEntity client_instance_path - Optional. Property path from the main instance to the instance to show the client (this is only used to convert DbEntityInterest to DbEntity) """ logger.debug("Creating InstanceBundle with kwargs: %s" % kwargs) self.user_id = kwargs['user_id'] self.has_keys = kwargs.get('instance_key') is not None or hasattr(kwargs['instance'], 'key') # An optional class-scope key, like the DbEntity key of Features self.class_key = kwargs.get('class_key') self.client_instance_path = kwargs.get('client_instance_path') if hasattr(kwargs['instance'], '__iter__'): self.ids = map(lambda instance: instance.id, kwargs['instance']) self.class_path = full_module_path(kwargs['instance'][0].__class__) # Backup for dynamic subclass resolution self.model_path = resolvable_model_name(kwargs['instance'][0].__class__) self.keys = map(lambda instance: kwargs.get('instance_key'), self.instances) if self.has_keys else [] else: instance = kwargs['instance'] self.ids = [instance.id] self.class_path = full_module_path(kwargs['instance'].__class__) # Backup for dynamic subclass resolution self.model_path = resolvable_model_name(kwargs['instance'].__class__) self.keys = [kwargs['instance_key'] if kwargs.get('instance_key', None) else self.instances[0].key] if self.has_keys else [] # Overrides the instance class of the instance for sending to the client self.override_class_path = full_module_path(kwargs['instance_class']) if kwargs.get('instance_class') else None
def get_db_prep_value(self, value, connection=None, prepared=False): """ Simplify the model instance to an id and class name to avoid expensive pickling """ mapped_dict = map_dict_to_dict(lambda key, inner_dict: [key, map_dict_to_dict(lambda inner_key, model_instance: [inner_key, dict( class_name=resolvable_model_name(model_instance.__class__), pk=self.pk_of_model(model_instance) )] if model_instance else None, # Should never be null, but sometimes i inner_dict )], value) return super(SelectionModelsPickledObjectField, self).get_db_prep_value(mapped_dict, connection, prepared)
def get_db_prep_value(self, value, connection=None, prepared=False): """ Simplify the model instance to an id and class name to avoid expensive pickling """ mapped_dict = map_dict_to_dict( lambda key, inner_dict: [ key, map_dict_to_dict( lambda inner_key, model_instance: [ inner_key, dict(class_name=resolvable_model_name(model_instance. __class__), pk=self.pk_of_model(model_instance)) ] if model_instance else None, # Should never be null, but sometimes i inner_dict) ], value) return super(SelectionModelsPickledObjectField, self).get_db_prep_value(mapped_dict, connection, prepared)