# -*- coding: utf-8 -*-
# http://djangosnippets.org/snippets/2672/
# myapp/management/commands/reversion_clean.py
u'''
If you use this pattern to track changes in the auth user table:
from django.contrib.auth.models import User
from reversion.helpers import patch_admin
patch_admin(User)
you can't see important changes, since a version is created for every
login if a user. If you want to get rid of changes which only change
unimportant stuff you can use this middleware.
Edit your settings. Example:
REVERSION_CLEAN={
'django.contrib.auth': {'User': ['last_login']},
}
Usage: manage.py reversion_clean
'''
import logging
from django.conf import settings
from django.core.management.base import NoArgsCommand, CommandError
from django.utils import importlib
from django.contrib.contenttypes.models import ContentType
from reversion.models import Version
class Command(NoArgsCommand):
help = "Clean unimportant changes in reversion history. Example: settings.py: REVERSION_CLEAN={'django.contrib.auth': {'User': ['last_login']}}"
requires_model_validation = False
def handle_noargs(self, **options):
rootLogger = logging.getLogger('')
rootLogger.setLevel(logging.INFO)
ignores=getattr(settings, 'REVERSION_CLEAN', None)
if not ignores:
raise CommandError('Error: settings.REVERSION_CLEAN is not set or empty.')
empty_count=0
only_ignore_count=0
ok_count=0
layout_count=0
for app, models in ignores.items():
import_str='%s.models' % app
modul=importlib.import_module(import_str)
for model, ignore_changes_attrs in models.items():
model_class=getattr(modul, model)
ct=ContentType.objects.get_for_model(model_class)
last=None
for version in Version.objects.filter(content_type=ct).order_by('object_id', 'id'):
if last is None:
last=version.get_field_dict()
continue
this=version.get_field_dict()
if set(this.keys())-set(last.keys()):
layout_count+=1
continue # DB Layout has changed. Don't delete
diff=dict()
for (this_key, this_value), (last_key, last_value) in zip(sorted(this.items()), sorted(last.items())):
assert this_key==last_key
if this_value==last_value:
continue
diff[this_key]=(this_value, last_value)
if not diff:
logging.info('no changes in Version %s' % version)
version.delete()
empty_count+=1
continue
if set(diff.keys()).issubset(ignore_changes_attrs):
logging.info('only changes to ignore: %s' % diff)
version.delete()
only_ignore_count+=1
continue
ok_count+=1
logging.info('Empty version: %s (del) Only ignore columns changed: %s (del) DB-Layout changed: %s (no-del) unchanged: %s (no-del)' % (
empty_count, only_ignore_count, layout_count, ok_count))
Comments