Danny Adair
unread,Oct 16, 2016, 11:28:47 PM10/16/16Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Sign in to report message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
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