def createTab(tab_name, user, workspace, allow_renaming=False): visible = False tabs = Tab.objects.filter(workspace=workspace, visible=True) if tabs.count() == 0: visible = True # It's always the last tab position = Tab.objects.filter(workspace=workspace).count() # Creating tab tab = Tab(name=tab_name, visible=visible, position=position, workspace=workspace) try: tab.save() except IntegrityError: if allow_renaming: save_alternative(Tab, 'name', tab) else: raise return tab
def clone_tuple(self, tuple): meta = tuple._meta table_name = meta.object_name # Controlling when a final table is reached! if self.is_final_table(table_name): return tuple # Controlling when a tuple has been previously cloned! new_id = self.mapping.get_mapping(table_name, tuple.id) if new_id: return get_tuple(meta.app_label, meta.module_name, new_id) else: model = get_model(meta.app_label, table_name) cloned_tuple = model() fields = meta.fields fields_to_overwrite = self.fields_to_overwrite.get(table_name, {}) # Cloning all object data! for field in fields: if isinstance(field, models.ForeignKey): # get the id of the foreignKey. It may be optional (None) fkValue = getattr(tuple, field.name) if fkValue: fkValue = self.clone_tuple(fkValue) setattr(cloned_tuple, field.name, fkValue) elif field != meta.auto_field: if field.name in fields_to_overwrite: value = fields_to_overwrite[field.name] else: value = getattr(tuple, field.name) setattr(cloned_tuple, field.name, value) # Getting an id! try: cloned_tuple.save() except IntegrityError: variant_field = self.unique_variant.get(table_name, None) if variant_field == None: raise save_alternative(model, variant_field, cloned_tuple) self.mapping.add_mapping(table_name, tuple.id, cloned_tuple.id) ########################################################################################################## #Marking many_to_many relationships to be updated when involved tuples are both cloned! # Many to many relationships can be iterated over in two different ways: #1. cloned FROM-SIDE table first m2m_fields = meta.many_to_many for m2m_field in m2m_fields: field_name = m2m_field.attname m2m_objects = getattr(tuple, field_name).all() for m2m_object in m2m_objects: referenced_meta = m2m_object._meta referenced_tuple_id = m2m_object.id self.m2ms.add_m2m_info(old_from_id=tuple.id, new_from_id=cloned_tuple.id, from_meta=meta, from_field=field_name, old_to_id=referenced_tuple_id, new_to_id=None, to_meta=referenced_meta) #2. cloned TO-SIDE table first m2m_related_fields = meta._related_many_to_many_cache for m2m_field in m2m_related_fields: reverse_rel_name = '%s_set' % m2m_field.var_name from_field = m2m_field.field.name m2m_objects = getattr(tuple, reverse_rel_name).all() for m2m_object in m2m_objects: referenced_meta = m2m_object._meta old_from_id = m2m_object.id self.m2ms.add_m2m_info(old_from_id=old_from_id, new_from_id=None, from_meta=referenced_meta, from_field=from_field, old_to_id=tuple.id, new_to_id=cloned_tuple.id, to_meta=meta) ########################################################################################################### # Continue iterating over data-model structure extra_models = self.extra_models.get(table_name, []) for model in extra_models: lookup = {} if len(model) > 3: lookup = model[3] related_tuples = get_related_tuples(model[0], # app_label model[1], # module_name model[2], # field.name tuple.id, lookup) for related_tuple in related_tuples: self.clone_tuple(related_tuple) return cloned_tuple