def end(self): """Ends a revision.""" self.assert_active() self._state.depth -= 1 # Handle end of revision conditions here. if self._state.depth == 0: models = self._state.objects try: if models and not self.is_invalid(): # Follow relationships. revision_set = self.follow_relationships(models) # Because we might have uncomitted data in models, we need to # replace the models in revision_set which might have come from the # db, with the actual models sent to reversion. diff = revision_set.difference(models) revision_set = models.union(diff) # Create all the versions without saving them new_versions = [] for obj in revision_set: # Proxy models should not actually be saved to the revision set. if obj._meta.proxy: continue registration_info = self.get_registration_info(obj.__class__) object_id = unicode(obj.pk) content_type = ContentType.objects.get_for_model(obj) serialized_data = serializers.serialize(registration_info.format, [obj], fields=registration_info.fields) new_versions.append(Version(object_id=object_id, content_type=content_type, format=registration_info.format, serialized_data=serialized_data, object_repr=unicode(obj))) # Check if there's some change in all the revision's objects. save_revision = True if self._state.ignore_duplicates: # Find the latest revision amongst the latest previous version of each object. subqueries = [Q(object_id=version.object_id, content_type=version.content_type) for version in new_versions] subqueries = reduce(operator.or_, subqueries) latest_revision = Version.objects.filter(subqueries).aggregate(Max("revision"))["revision__max"] # If we have a latest revision, compare it to the current revision. if latest_revision is not None: previous_versions = Version.objects.filter(revision=latest_revision).values_list("serialized_data", flat=True) if len(previous_versions) == len(new_versions): all_serialized_data = [version.serialized_data for version in new_versions] if sorted(previous_versions) == sorted(all_serialized_data): save_revision = False # Only save if we're always saving, or have changes. if save_revision: # Save a new revision. revision = Revision.objects.create(user=self._state.user, comment=self._state.comment) # Save version models. for version in new_versions: version.revision = revision version.save() # Save the meta information. for cls, kwargs in self._state.meta: cls._default_manager.create(revision=revision, **kwargs) finally: self._state.clear()
def end(self): """Ends a revision.""" self.assert_active() self._state.depth -= 1 # Handle end of revision conditions here. if self._state.depth == 0: models = self._state.objects try: if models and not self.is_invalid(): # Save a new revision. revision = Revision.objects.create(user=self._state.user, comment=self._state.comment) # Follow relationships. revision_set = self.follow_relationships(self._state.objects) # Because we might have uncomitted data in models, we need to # replace the models in revision_set which might have come from the # db, with the actual models sent to reversion. diff = revision_set.difference(models) revision_set = models.union(diff) # Save version models. versions_created = False for obj in revision_set: # Proxy models should not actually be saved to the revision set. if obj._meta.proxy: continue registration_info = self.get_registration_info(obj.__class__) object_id = unicode(obj.pk) content_type = ContentType.objects.get_for_model(obj) serialized_data = serializers.serialize(registration_info.format, [obj], fields=registration_info.fields) # Ensure we're not saving an exact replica of the previous version. # This can occur, for instance, if the user is only including certain fields # in version control. try: previous_version = Version.objects.get_for_date(obj, datetime.now()) if previous_version.serialized_data == serialized_data: continue except ObjectDoesNotExist: pass versions_created = True Version.objects.create(revision=revision, object_id=object_id, content_type=content_type, format=registration_info.format, serialized_data=serialized_data, object_repr=unicode(obj)) if not versions_created: # No changes were made to any models that required a revision, roll back. revision.delete() else: for cls, kwargs in self._state.meta: cls._default_manager.create(revision=revision, **kwargs) finally: self._state.clear()
def end(self): """Ends a revision.""" self.assert_active() self._state.depth -= 1 # Handle end of revision conditions here. if self._state.depth == 0: models = self._state.objects try: if models and not self.is_invalid(): # Save a new revision. revision = Revision.objects.create(user=self._state.user, comment=self._state.comment) # Follow relationships. revision_set = self.follow_relationships(self._state.objects) # Because we might have uncomitted data in models, we need to # replace the models in revision_set which might have come from the # db, with the actual models sent to reversion. diff = revision_set.difference(models) revision_set = models.union(diff) # Save version models. for obj in revision_set: # Proxy models should not actually be saved to the revision set. if obj._meta.proxy: continue registration_info = self.get_registration_info(obj.__class__) object_id = unicode(obj.pk) content_type = ContentType.objects.get_for_model(obj) serialized_data = serializers.serialize(registration_info.format, [obj], fields=registration_info.fields) Version.objects.create(revision=revision, object_id=object_id, content_type=content_type, format=registration_info.format, serialized_data=serialized_data, object_repr=unicode(obj)) # unset deletions... Version.objects.filter(object_id=object_id, content_type=content_type, is_deleted=True).update(is_deleted=False) for cls, kwargs in self._state.meta: cls._default_manager.create(revision=revision, **kwargs) finally: self._state.clear()
def end(self): """Ends a revision.""" self.assert_active() self._state.depth -= 1 # Handle end of revision conditions here. if self._state.depth == 0: models = self._state.objects try: if models and not self.is_invalid(): # Save a new revision. revision = Revision.objects.create(user=self._state.user, comment=self._state.comment) # Follow relationships. revision_set = self.follow_relationships(self._state.objects) # Because we might have uncomitted data in models, we need to # replace the models in revision_set which might have come from the # db, with the actual models sent to reversion. diff = revision_set.difference(models) revision_set = models.union(diff) # Save version models. for obj in revision_set: # Proxy models should not actually be saved to the revision set. if obj._meta.proxy: continue registration_info = self.get_registration_info(obj.__class__) object_id = unicode(obj.pk) content_type = ContentType.objects.get_for_model(obj) serialized_data = serializers.serialize(registration_info.format, [obj], fields=registration_info.fields) Version.objects.create(revision=revision, object_id=object_id, content_type=content_type, format=registration_info.format, serialized_data=serialized_data, object_repr=unicode(obj)) for cls, kwargs in self._state.meta: cls._default_manager.create(revision=revision, **kwargs) finally: self._state.clear()
def end(self): """Ends a revision.""" self.assert_active() self._state.depth -= 1 # Handle end of revision conditions here. if self._state.depth == 0: models = self._state.objects try: if models and not self.is_invalid(): # Follow relationships. revision_set = self.follow_relationships(models) # Because we might have uncomitted data in models, we need to # replace the models in revision_set which might have come from the # db, with the actual models sent to reversion. diff = revision_set.difference(models) revision_set = models.union(diff) # Create all the versions without saving them new_versions = [] for obj in revision_set: # Proxy models should not actually be saved to the revision set. if obj._meta.proxy: continue registration_info = self.get_registration_info( obj.__class__) object_id = unicode(obj.pk) content_type = ContentType.objects.get_for_model(obj) serialized_data = serializers.serialize( registration_info.format, [obj], fields=registration_info.fields) new_versions.append( Version(object_id=object_id, content_type=content_type, format=registration_info.format, serialized_data=serialized_data, object_repr=unicode(obj))) # Check if there's some change in all the revision's objects. save_revision = True if self._state.ignore_duplicates: # Find the latest revision amongst the latest previous version of each object. subqueries = [ Q(object_id=version.object_id, content_type=version.content_type) for version in new_versions ] subqueries = reduce(operator.or_, subqueries) latest_revision = Version.objects.filter( subqueries).aggregate( Max("revision"))["revision__max"] # If we have a latest revision, compare it to the current revision. if latest_revision is not None: previous_versions = Version.objects.filter( revision=latest_revision).values_list( "serialized_data", flat=True) if len(previous_versions) == len(new_versions): all_serialized_data = [ version.serialized_data for version in new_versions ] if sorted(previous_versions) == sorted( all_serialized_data): save_revision = False # Only save if we're always saving, or have changes. if save_revision: # Save a new revision. revision = Revision.objects.create( user=self._state.user, comment=self._state.comment) # Save version models. for version in new_versions: version.revision = revision version.save() # Save the meta information. for cls, kwargs in self._state.meta: cls._default_manager.create(revision=revision, **kwargs) finally: self._state.clear()
def end(self): """Ends a revision.""" self.assert_active() self._state.depth -= 1 # Handle end of revision conditions here. if self._state.depth == 0: models = self._state.objects dead_models = self._state.dead_objects models -= dead_models try: if (dead_models or models) and not self.is_invalid(): # Save a new revision. revision = Revision.objects.create(user=self._state.user, comment=self._state.comment) # Follow relationships. revision_set = \ self.follow_relationships(self._state.objects) # Because we might have uncomitted data in models, we need # to replace the models in revision_set which might have # come from the db, with the actual models sent to # reversion. diff = revision_set.difference(models) revision_set = models.union(diff) # Save version models. for obj in revision_set: # Proxy models should not actually be saved to the # revision set. if obj._meta.proxy: continue action = obj._reversion.action registration_info = self.get_registration_info(obj.__class__) object_id = unicode(obj.pk) content_type = ContentType.objects.get_for_model(obj) if action is DELETION: raise ValueError, "BUG: there's a dead model " \ "among live ones. %r" % obj else: ancestors_and_self = \ self.follow_relationships([obj], ancestors=True) serialized_data = \ serializers.serialize(registration_info.format, ancestors_and_self, fields=registration_info.fields) Version.objects.create(revision=revision, object_id=object_id, content_type=content_type, format=registration_info.format, serialized_data=serialized_data, object_repr=unicode(repr(obj)), action_flag=action) # For objects that have already been deleted, get the stored # serialized data and attach it to the version. for obj in dead_models: action = obj._reversion.action assert action is DELETION, "%r action: %d" % (obj, action) registration_info = self.get_registration_info(obj.__class__) object_id = unicode(obj.pk) content_type = ContentType.objects.get_for_model(obj) serialized_data = obj._reversion.serialized_data original_repr = obj._reversion.repr Version.objects.create(revision=revision, object_id=object_id, content_type=content_type, format=registration_info.format, serialized_data=serialized_data, object_repr=unicode(original_repr), action_flag=action) for cls, kwargs in self._state.meta: cls._default_manager.create(revision=revision, **kwargs) finally: self._state.clear()