Exemplo n.º 1
0
def _save_revision(versions,
                   user=None,
                   comment="",
                   meta=(),
                   date_created=None,
                   using=None):
    from reversion.models import Revision
    # Bail early if there are no objects to save.
    if not versions:
        return
    # Save a new revision.
    revision = Revision(
        date_created=date_created,
        user=user,
        comment=comment,
    )
    # Save the revision.
    revision.save(using=using)
    # Save version models.
    for version in versions:
        version.revision = revision
        version.save(using=using)
    # Save the meta information.
    for meta_model, meta_fields in meta:
        meta_model._default_manager.db_manager(using=using).create(
            revision=revision, **meta_fields)
Exemplo n.º 2
0
def _save_revision(versions,
                   user=None,
                   comment="",
                   meta=(),
                   date_created=None,
                   using=None):
    from reversion.models import Revision
    # Only save versions that exist in the database.
    # Use _base_manager so we don't have problems when _default_manager is overriden
    model_db_pks = defaultdict(lambda: defaultdict(set))
    for version in versions:
        model_db_pks[version._model][version.db].add(version.object_id)
    model_db_existing_pks = {
        model: {
            db: frozenset(
                map(
                    force_str,
                    model._base_manager.using(db).filter(
                        pk__in=pks).values_list("pk", flat=True),
                ))
            for db, pks in db_pks.items()
        }
        for model, db_pks in model_db_pks.items()
    }
    versions = [
        version for version in versions if version.object_id in
        model_db_existing_pks[version._model][version.db]
    ]
    # Bail early if there are no objects to save.
    if not versions:
        return
    # Save a new revision.
    revision = Revision(
        date_created=date_created,
        user=user,
        comment=comment,
    )
    # Send the pre_revision_commit signal.
    pre_revision_commit.send(
        sender=create_revision,
        revision=revision,
        versions=versions,
    )
    # Save the revision.
    revision.save(using=using)
    # Save version models.
    for version in versions:
        version.revision = revision
        version.save(using=using)
    # Save the meta information.
    for meta_model, meta_fields in meta:
        meta_model._base_manager.db_manager(using=using).create(
            revision=revision, **meta_fields)
    # Send the post_revision_commit signal.
    post_revision_commit.send(
        sender=create_revision,
        revision=revision,
        versions=versions,
    )
Exemplo n.º 3
0
def update_metric(revision, sender, signal, versions, **kwargs):
    version2 = versions[0]
    fields2 = json.loads(version2.serialized_data)[0]['fields']
    if version2.content_type_id == ContentType.objects.get_for_model(Probe).id:
        version1 = Version.objects.get_for_object(
            Probe.objects.get(id=version2.object_id))[1]

        # getting old probeversion from the second entry in VersionQuerySet
        fields1 = json.loads(version1.serialized_data)[0]['fields']
        old_probeversion = u'%s (%s)' % (fields1['name'], fields1['version'])

        # getting new probeversion from the first entry in VersionQuerySet
        new_probeversion = u'%s (%s)' % (fields2['name'], fields2['version'])

        metric_pk = Metric.objects.filter(
            probeversion=old_probeversion).values_list('id', flat=True)
        ct = ContentType.objects.get_for_model(Metric)

        vers = list()
        for pk in metric_pk:
            instance = Metric.objects.get(id=pk)
            instance.probeversion = new_probeversion
            instance.probekey = version2
            instance.save()
            LogEntry.objects.log_action(user_id=revision.user_id,
                                        content_type_id=ct.id,
                                        object_id=pk,
                                        object_repr=instance.__str__(),
                                        action_flag=CHANGE,
                                        change_message='Changed probeversion.')
            metric_ver = Version.objects.filter(object_id=pk,
                                                content_type_id=ct.id)

            rev = Revision(date_created=revision.date_created,
                           user_id=revision.user_id,
                           comment='[{"changed": {"fields": ['
                           '"probeversion"]}}]')

            ver = Version(object_id=str(instance.id),
                          content_type_id=ct.id,
                          format=metric_ver[0].format,
                          serialized_data=metric_ver[0].serialized_data,
                          object_repr=metric_ver[0].object_repr,
                          db='default')
            rev.save()

            Revision.objects.filter(pk=rev.id).update(
                date_created=revision.date_created)
            ver.revision = rev
            data = json.loads(metric_ver[0].serialized_data)[0]
            data['fields']['probeversion'] = new_probeversion
            data['fields']['probekey'] = version2.id
            ver.serialized_data = json.dumps([data])
            vers.append(ver)

        Version.objects.bulk_create(vers)
Exemplo n.º 4
0
def _save_revision(versions, user=None, comment="", meta=(), date_created=None, using=None):
    from reversion.models import Revision
    # Bail early if there are no objects to save.
    if not versions:
        return
    # Save a new revision.
    with transaction.atomic(using=using):  # altered from original. Normally _save_revision is run wintin atomic context
        revision = Revision(
            date_created=date_created,
            user=user,
            comment=comment,
        )
        # Send the pre_revision_commit signal.
        pre_revision_commit.send(
            sender=create_revision,
            revision=revision,
            versions=versions,
        )
        # Save the revision.
        revision.save(using=using)
        # Save version models.
        for version in versions:
            version.revision = revision
            version.save(using=using)
        # Save the meta information.
        for meta_model, meta_fields in meta:
            meta_model._default_manager.db_manager(using=using).create(
                revision=revision,
                **meta_fields
            )
        # Send the post_revision_commit signal.
        post_revision_commit.send(
            sender=create_revision,
            revision=revision,
            versions=versions,
        )
Exemplo n.º 5
0
 def save_revision(self, objects, ignore_duplicates=False, user=None, comment="", meta=(), db=None):
     """Saves a new revision."""
     # Get the db alias.
     db = db or DEFAULT_DB_ALIAS
     # Adapt the objects to a dict.
     if isinstance(objects, (list, tuple)):
         objects = dict(
             (obj, self.get_adapter(obj.__class__).get_version_data(obj, db))
             for obj in objects
         )
     # Create the revision.
     if objects:
         # Follow relationships.
         for obj in self._follow_relationships(objects.keys()):
             if not obj in objects:
                 adapter = self.get_adapter(obj.__class__)
                 objects[obj] = adapter.get_version_data(obj)
         # Create all the versions without saving them
         ordered_objects = list(objects.keys())
         new_versions = [Version(**objects[obj]) for obj in ordered_objects]
         # Check if there's some change in all the revision's objects.
         save_revision = True
         if 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 = self._get_versions(db).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 = self._get_versions(db).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(
                 manager_slug = self._manager_slug,
                 user = user,
                 comment = comment,
             )
             # Send the pre_revision_commit signal.
             pre_revision_commit.send(self,
                 instances = ordered_objects,
                 revision = revision,
                 versions = new_versions,
             )
             # Save the revision.
             with transaction.atomic(using=db):
                 revision.save(using=db)
                 # Save version models.
                 for version in new_versions:
                     version.revision = revision
                 Version.objects.using(db).bulk_create(new_versions)
                 # Save the meta information.
                 for cls, kwargs in meta:
                     cls._default_manager.db_manager(db).create(revision=revision, **kwargs)
             # Send the pre_revision_commit signal.
             post_revision_commit.send(self,
                 instances = ordered_objects,
                 revision = revision,
                 versions = new_versions,
             )
             # Return the revision.
             return revision
Exemplo n.º 6
0
def _save_revision(versions,
                   user=None,
                   comment="",
                   meta=(),
                   date_created=None,
                   using=None):
    from reversion.models import Revision
    # Only save versions that exist in the database.
    # Use _base_manager so we don't have problems when _default_manager is overriden
    model_db_pks = defaultdict(lambda: defaultdict(set))
    for version in versions:
        model_db_pks[version._model][version.db].add(version.object_id)
    model_db_existing_pks = {
        model: {
            db: frozenset(
                map(
                    force_str,
                    model._base_manager.using(db).filter(
                        pk__in=pks).values_list("pk", flat=True),
                ))
            for db, pks in db_pks.items()
        }
        for model, db_pks in model_db_pks.items()
    }
    versions = [
        version for version in versions if version.object_id in
        model_db_existing_pks[version._model][version.db]
    ]
    # Bail early if there are no objects to save.
    if not versions:
        return
    # Save a new revision.
    revision = Revision(
        date_created=date_created,
        user=user,
        comment=comment,
    )
    # Send the pre_revision_commit signal.
    pre_revision_commit.send(
        sender=create_revision,
        revision=revision,
        versions=versions,
    )
    # Save the revision.
    revision.save(using=using)
    # Save version models.
    for version in versions:
        version.revision = revision
        version.save(using=using)
    # Save the meta information.
    for meta_inst_or_model, meta_fields in meta:

        # Default meta class and primary key
        meta_class = meta_inst_or_model
        pk = None

        # Add the revision to the fields that will be added/updated
        meta_fields['revision'] = revision

        # If the supplied meta_model is an instance, we need to ensure the
        # correct class is used when updating as well as be able to query
        # the meta instance properly
        if isinstance(meta_inst_or_model, (models.Model, )):
            # Fetch the class used to make the update
            meta_class = meta_inst_or_model.__class__
            pk = meta_inst_or_model.pk

        # Call update or create
        meta_class._base_manager.db_manager(using=using).update_or_create(
            pk=pk, defaults=meta_fields)

    # Send the post_revision_commit signal.
    post_revision_commit.send(
        sender=create_revision,
        revision=revision,
        versions=versions,
    )
Exemplo n.º 7
0
def _save_revision(versions, user=None, comment="", meta=(), date_created=None, using=None):
    from reversion.models import Revision
    # Only save versions that exist in the database.
    model_db_pks = defaultdict(lambda: defaultdict(set))
    for version in versions:
        model_db_pks[version._model][version.db].add(version.object_id)
    model_db_existing_pks = {
        model: {
            db: frozenset(map(
                force_text,
                model._default_manager.using(db).filter(pk__in=pks).values_list("pk", flat=True),
            ))
            for db, pks in db_pks.items()
            }
        for model, db_pks in model_db_pks.items()
        }
    custom_models = getattr(settings, 'DJANGO_REVISION_CUSTOM_MODELS', False)

    if custom_models:
        if hasattr(settings, 'DJANGO_REVISION_EXCLUDED_MODELS'):
            versions = [
                version for version in versions
                if version._model._meta.object_name not in settings.DJANGO_REVISION_EXCLUDED_MODELS and
                version.object_id in model_db_existing_pks[version._model][version.db]
                ]
        elif hasattr(settings, 'DJANGO_REVISION_ALLOWED_MODELS'):
            versions = [
                version for version in versions
                if version._model._meta.object_name in settings.DJANGO_REVISION_ALLOWED_MODELS and
                version.object_id in model_db_existing_pks[version._model][version.db]
                ]
        else:
            raise ImproperlyConfigured(
                "Using 'DJANGO_REVISION_CUSTOM_MODELS' without either the 'DJANGO_REVISION_EXCLUDED_MODELS' in"
                " settings or the 'DJANGO_REVISION_ALLOWED_MODELS' in settings is prohibited.")
    else:
        versions = [
            version for version in versions
            if version.object_id in model_db_existing_pks[version._model][version.db]
            ]
    # Bail early if there are no objects to save.
    if not versions:
        return
    # Save a new revision.
    revision = Revision(
        date_created=date_created,
        user=user,
        comment=comment,
    )
    # Send the pre_revision_commit signal.
    pre_revision_commit.send(
        sender=create_revision,
        revision=revision,
        versions=versions,
    )
    # Save the revision.
    revision.save(using=using)
    # Save version models.
    for version in versions:
        version.revision = revision
        version.save(using=using)
    # Save the meta information.
    for meta_model, meta_fields in meta:
        meta_model._default_manager.db_manager(using=using).create(
            revision=revision,
            **meta_fields
        )
    # Send the post_revision_commit signal.
    post_revision_commit.send(
        sender=create_revision,
        revision=revision,
        versions=versions,
    )
Exemplo n.º 8
0
def _save_revision(versions,
                   user=None,
                   comment="",
                   meta=(),
                   date_created=None,
                   using=None):
    from reversion.models import Revision
    # Only save versions that exist in the database.
    model_db_pks = defaultdict(lambda: defaultdict(set))
    for version in versions:
        model_db_pks[version._model][version.db].add(version.object_id)
    model_db_existing_pks = {
        model: {
            db: frozenset(
                map(
                    force_text,
                    model._default_manager.using(db).filter(
                        pk__in=pks).values_list("pk", flat=True),
                ))
            for db, pks in db_pks.items()
        }
        for model, db_pks in model_db_pks.items()
    }
    versions = [
        version for version in versions if version.object_id in
        model_db_existing_pks[version._model][version.db]
    ]
    # Bail early if there are no objects to save.
    if not versions:
        return
    # Save a new revision.
    revision = Revision(
        date_created=date_created,
        user=user,
        comment=comment,
    )
    # Send the pre_revision_commit signal.
    pre_revision_commit.send(
        sender=create_revision,
        revision=revision,
        versions=versions,
    )
    # Save the revision.
    revision.save(using=using)
    # Save version models.
    # XXX magic numbers because base content needs to be saved before children
    BASE_CONTENT_TYPE_ID = 18
    versions = sorted(
        versions,
        key=lambda v:
        (0
         if v.content_type_id == BASE_CONTENT_TYPE_ID else v.content_type_id))
    for version in versions:
        version.revision = revision
        version.save(using=using)
    # Save the meta information.
    for meta_model, meta_fields in meta:
        meta_model._default_manager.db_manager(using=using).create(
            revision=revision, **meta_fields)
    # Send the post_revision_commit signal.
    post_revision_commit.send(
        sender=create_revision,
        revision=revision,
        versions=versions,
    )
Exemplo n.º 9
0
def _save_revision(versions,
                   user=None,
                   comment="",
                   meta=(),
                   date_created=None,
                   using=None):
    from reversion.models import Revision
    # Only save versions that exist in the database.
    # Use _base_manager so we don't have problems when _default_manager is overriden
    model_db_pks = defaultdict(lambda: defaultdict(set))
    for version in versions:
        model_db_pks[version._model][version.db].add(version.object_id)

    def _safe_get_pks(model, db, pks):
        """
        Hack: helper function for use with django-safedelete package
        so we avoid committing versions for objects that have already
        been safe deleted

        See hack in models VersionQuerySet get_deleted too
        """
        try:
            from safedelete.models import is_safedelete_cls
        except ImportError:
            is_safedelete_cls = lambda: False

        if is_safedelete_cls(model):
            # Use the safedelete manager to ensure we exclude "soft-deleted"
            # obj versions
            return model._default_manager.using(db).filter(pk__in=pks)\
                .values_list("pk", flat=True)
        # Else: not using softdelete for this model so use base manager as in
        # original django-revision
        return model._base_manager.using(db).filter(pk__in=pks)\
            .values_list("pk", flat=True)

    model_db_existing_pks = {
        model: {
            db: frozenset(map(
                force_text,
                _safe_get_pks(model, db, pks),
            ))
            for db, pks in db_pks.items()
        }
        for model, db_pks in model_db_pks.items()
    }
    versions = [
        version for version in versions if version.object_id in
        model_db_existing_pks[version._model][version.db]
    ]
    # Bail early if there are no objects to save.
    if not versions:
        return
    # Save a new revision.
    revision = Revision(
        date_created=date_created,
        user=user,
        comment=comment,
    )
    # Send the pre_revision_commit signal.
    pre_revision_commit.send(
        sender=create_revision,
        revision=revision,
        versions=versions,
    )
    # Save the revision.
    revision.save(using=using)
    # Save version models.
    for version in versions:
        version.revision = revision
        version.save(using=using)
    # Save the meta information.
    for meta_model, meta_fields in meta:
        meta_model._base_manager.db_manager(using=using).create(
            revision=revision, **meta_fields)
    # Send the post_revision_commit signal.
    post_revision_commit.send(
        sender=create_revision,
        revision=revision,
        versions=versions,
    )