# -*- 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))