Login

Clean Reversion History: Remove unimportant Changes

Author:
guettli
Posted:
February 3, 2012
Language:
Python
Version:
1.3
Score:
0 (after 0 ratings)

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.

This middleware can be used for every model. Just use this pattern in your settings:

REVERSION_CLEAN={
    'django.contrib.auth': {'User': ['last_login']},
    }
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# -*- 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))

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 2 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 2 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 9 months, 2 weeks ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 10 months, 1 week ago
  5. Help text hyperlinks by sa2812 11 months ago

Comments

Please login first before commenting.