Custom meta data and pre_delete signals

55 views
Skip to first unread message

Danny Adair

unread,
Oct 16, 2016, 11:28:47 PM10/16/16
to django-reversion discussion group
Hi,

We're migrating from Django 1.3 to Django 1.8,
and from django-reversion 1.5.2 to 1.10.2.

I've got a field "something" on MyClass and on the recover_list.html I
only want to show those deleted MyClass instances with a specific
value for "something". Because there are about 50 million Version
objects in the database, I can't just inspect the serialized data as
that would take too long, so I save the "something" as custom meta
data for fast filtering.
(so yeah I'm overriding recoverlist_view() for that filtering and that works)

I have issues with the signals I'm using to attach this custom meta
data: post_save and pre_delete. These issues don't seem to have been
present in the old version.
With the code below

=========================================================
from django.db.models.signals import post_save, pre_delete
from django.dispatch import receiver
import reversion
from reversion.revisions import revision_context_manager
from .models import MyModel

@receiver(pre_delete, sender=MyModel, dispatch_uid='mymodel_pre_delete_signal')
@receiver(post_save, sender=MyModel, dispatch_uid='mymodel_post_save_signal')
def attach_something_as_meta(sender, instance, using=None, **kwargs):
"""
Attach custom meta data 'something' to reversion's current revision.
Used for fast filtering on 'Recover deleted' screen.

TODO: What if a revision has multiple objects/versions in it that relate
to different somethings?
"""
# If a MyMeta is already created against the current revision,
# don't create another one.
for meta in revision_context_manager._current_frame.meta:
if meta[0]==MyMeta:
# Already a MyMeta in meta
return None
reversion.revisions.add_meta(MyMeta, something=instance.something)
=========================================================

1. My main problem is that pre_delete does trigger this function but
the add_meta() doesn't lead to a new MyMeta instance. That only
happens on pre_save. Why?

2. After clicking on a deleted object in the recover list,
recover_view() already reverts the Version, and calls
self.object_version.save() which triggers the post_save() signal. So
before I even click "Save" I've already created a new revision and a
new MyMeta, and once I click I have two revisions and two MyMetas.
I'm sure there's reasons (would be curious which) but I'd prefer not
to grow MyMeta from actions that didn't change the database.
I used to check the "current revision" for existing meta (see code
above) so I don't create another. That would happen when a post_save()
saved MyMeta, then the object got deleted and pre_delete() shouldn't
attach it again. Another option would be that I just not trigger on
pre_delete at all (you can only delete something that was saved
before) but I'm doing that because a lot of existing revisions don't
have MyMeta attached yet. (I introduced MyMeta when I ran into the
problem of slow filtering.)
With the "early revert" behaviour above, it makes sense that
revision_context_manager._current_frame.meta is always empty on the
recover form, because a new revision gets created so early and that
doesn't have the meta data yet. However, when I delete an object that
does have MyMeta attached to it, pre_delete triggering this function
also shows no MyMeta. Again an unexpected behaviour of meta data in
pre_delete. Do you know why? What is the "current revision" at that
point and how can I check its meta?

I hope the above makes sense, thank you for any pointers.

Cheers,
Danny

Dave Hall

unread,
Oct 17, 2016, 5:52:11 AM10/17/16
to django-reversion discussion group
Is your issue that the post_revision_commit and pre_revision_commit signals have been removed from django-reversion?

If so, then do not fear! They're back in the master branch!

--
You received this message because you are subscribed to the Google Groups "django-reversion discussion group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-reversi...@googlegroups.com.
To post to this group, send an email to django-r...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-reversion.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages