def add_to_revision(instance, revision_set): """ Calculates the objects that should be included in the same revision as the given instance. All calculated objects are added to the `revision_set`. """ # Prevent recursion. if instance in revision_set: return revision_set.add(instance) # Follow relations. fields, follow, format = get_registration_info(instance.__class__) if follow: for relationship in follow: try: # Clear foreign key cache. related_field = instance._meta.get_field(relationship) if isinstance(related_field, models.ForeignKey): if hasattr(instance, related_field.get_cache_name()): delattr(instance, related_field.get_cache_name()) except models.FieldDoesNotExist: pass related = getattr(instance, relationship, None) if isinstance(related, models.Model): add_to_revision(related, revision_set) elif isinstance(related, (models.Manager, QuerySet)): for related_obj in related.all(): add_to_revision(related_obj, revision_set) elif related is not None: raise TypeError, "Cannot follow the relationship '%s', unexpected type %s" % ( relationship, type(related).__name__)
def add_to_revision(instance, revision_set): """ Calculates the objects that should be included in the same revision as the given instance. All calculated objects are added to the `revision_set`. """ # Prevent recursion. if instance in revision_set: return revision_set.add(instance) # Follow relations. fields, follow, format = get_registration_info(instance.__class__) if follow: for relationship in follow: try: # Clear foreign key cache. related_field = instance._meta.get_field(relationship) if isinstance(related_field, models.ForeignKey): if hasattr(instance, related_field.get_cache_name()): delattr(instance, related_field.get_cache_name()) except models.FieldDoesNotExist: pass related = getattr(instance, relationship, None) if isinstance(related, models.Model): add_to_revision(related, revision_set) elif isinstance(related, (models.Manager, QuerySet)): for related_obj in related.all(): add_to_revision(related_obj, revision_set) elif related is not None: raise TypeError, "Cannot follow the relationship '%s', unexpected type %s" % (relationship, type(related).__name__)
def end(self): """Ends a revision.""" self._assert_active() self._depth -= 1 # Handle end of revision conditions here. if self._depth == 0: try: if self._versions and not self._is_invalid: # Save a new revision. revision = Revision.objects.create(user=self._user, comment=self._comment) revision_set = set() # Follow relationships. for version in self._versions: add_to_revision(version, revision_set) # Save version models. for obj in revision_set: fields, follow, format = get_registration_info(obj.__class__) object_id = unicode(obj.pk) content_type = ContentType.objects.get_for_model(obj) serialized_data = serializers.serialize(format, [obj], fields=fields) Version.objects.create(revision=revision, object_id=object_id, content_type=content_type, format=format, serialized_data=serialized_data, object_repr=unicode(obj)) for meta_cls, meta_kwargs in self._meta: meta_cls._default_manager.create(revision=revision, **meta_kwargs) finally: self._clear() return False