def sync_content(self,axilent_content): """ Syncs the local content to the incoming axilent content (a dictionary). """ from djax.content import DefaultFieldConverter local_model = self.get_local_model() field_map = local_model.ACE.field_map log.debug('syncing local model with Axilent content %s, using field map %s.' % (unicode(axilent_content),unicode(field_map))) # Iterate through the field map and set the local model values from the incoming Axilent content deferred_field_converters = [] for axilent_field, model_field in field_map.items(): if hasattr(model_field,'field'): # this is a field converter # sanity check if not hasattr(model_field,'to_ace') or not hasattr(model_field,'to_local_model'): raise ValueError('You must define the methods to_ace and to_local_model for field converter for ace field %s.' % axilent_field) # check deferred if hasattr(model_field,'deferred') and model_field.deferred: deferred_field_converters.append((axilent_field,model_field)) else: # check nullable if (hasattr(model_field,'accepts_null') and model_field.accepts_null) or hasattr(axilent_content,axilent_field): # this is a nullable field converter or a non-null value value = None if hasattr(axilent_content,axilent_field): # for non-null fields, use the supplied value value = model_field.to_local_model(axilent_content,getattr(axilent_content,axilent_field)) setattr(local_model,model_field.field,value) else: log.info('Skipping non-nullable field %s - not in data from ACE.' % axilent_field) else: # just a string, use default field converter if hasattr(axilent_content,axilent_field): default_field_converter = DefaultFieldConverter(model_field) setattr(local_model,model_field,default_field_converter.to_local_model(axilent_content,getattr(axilent_content,axilent_field))) else: log.info('Skipping default field %s - not in data from ACE.' % axilent_field) local_model.save() if deferred_field_converters: for deferred_axilent_field, deferred_model_field in deferred_field_converters: try: deferred_model_field.to_local_model(axilent_content,getattr(axilent_content,deferred_axilent_field),local_model) except AttributeError: log.exception('Local model has no field %s (matched to Axilent field %s).' % (deferred_model_field.field,deferred_axilent_field)) local_model.save() else: log.info('No deferred field converters for %s.' % unicode(local_model)) self.updated = datetime.now() self.save() return local_model
def create_model(self,axilent_content_type,axilent_content_key): """ Creates a new model and accompaning content record for the axilent content. """ from djax.content import DefaultFieldConverter log.debug('Creating new model of content type:%s and key:%s.' % (axilent_content_type,axilent_content_key)) build_registry() # ensure registry is built content_data = content_client.get_content(axilent_content_type,axilent_content_key) local_model, record = None, None try: model_class = content_registry[axilent_content_type] field_map = {} try: field_map = model_class.ACE.field_map except AttributeError: for key in content_data.data.keys(): field_map[key] = key # Iterate through the field map and set the local model values from the incoming Axilent content fields = {} deferred_field_converters = [] for axilent_field, model_field in field_map.items(): if hasattr(content_data,axilent_field): try: if hasattr(model_field,'field'): log.debug('%s using field converter %s.' % (axilent_field,unicode(model_field))) # this is a field converter # sanity check if not hasattr(model_field,'to_ace') or not hasattr(model_field,'to_local_model'): raise ValueError('You must define the methods to_ace and to_local_model for field converter for ace field %s.' % axilent_field) if hasattr(model_field,'deferred') and model_field.deferred: log.debug('%s uses a deferred field converter.' % axilent_field) deferred_field_converters.append((axilent_field,model_field)) else: log.debug('%s uses an immediate field converter.' % axilent_field) value = model_field.to_local_model(content_data,getattr(content_data,axilent_field)) fields[model_field.field] = value else: log.debug('Using default field converter for %s.' % axilent_field) # not a field converter, just a string. Use DefaultFieldConverter default_field_converter = DefaultFieldConverter(model_field) fields[model_field] = default_field_converter.to_local_model(content_data,getattr(content_data,axilent_field)) except AttributeError: log.exception('Local model has no field %s (matched to Axilent field %s).' % (model_field,axilent_field)) else: log.info('Skipping ace field %s - not in data from ace.' % axilent_field) log.debug('Creating local model with field data %s.' % unicode(fields)) local_model = model_class.objects.create(**fields) # create the local model with the content data if deferred_field_converters: for deferred_axilent_field, deferred_model_field in deferred_field_converters: try: deferred_model_field.to_local_model(content_data,getattr(content_data,deferred_axilent_field),local_model) except AttributeError: log.exception('Local model has no field %s (matched to Axilent field %s).' % (deferred_model_field.field,deferred_axilent_field)) local_model.save() else: log.info('No deferred field converters for %s.' % unicode(local_model)) local_content_type = ContentType.objects.get_for_model(local_model) record = self.create(local_content_type=local_content_type, local_id=local_model.pk, axilent_content_type=axilent_content_type, axilent_content_key=axilent_content_key, updated=datetime.now()) except KeyError: raise ValueError('ACE content type %s cannot be found in the local registry.' % axilent_content_type) return (local_model,record)