mirror of
https://github.com/jazzband/django-auditlog.git
synced 2026-03-16 22:20:26 +00:00
Merge pull request #22 from jjkester/python3
Support Python 3 as well as Python 2
This commit is contained in:
commit
ae8461d1fe
12 changed files with 54 additions and 20 deletions
11
.travis.yml
Normal file
11
.travis.yml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
language: python
|
||||
python:
|
||||
- "2.7"
|
||||
- "3.4"
|
||||
env:
|
||||
- DJANGO_VERSION=1.7
|
||||
- DJANGO_VERSION=1.8
|
||||
install:
|
||||
- "pip install -r requirements.txt"
|
||||
- "pip install Django==$DJANGO_VERSION"
|
||||
script: "python src/manage.py test testapp"
|
||||
|
|
@ -1 +1 @@
|
|||
Django>=1.5
|
||||
Django>=1.7
|
||||
|
|
|
|||
2
setup.py
2
setup.py
|
|
@ -11,6 +11,6 @@ setup(
|
|||
author_email='janjelle@jjkester.nl',
|
||||
description='Audit log app for Django',
|
||||
install_requires=[
|
||||
'Django>=1.5'
|
||||
'Django>=1.7'
|
||||
]
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
from __future__ import unicode_literals
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db.models import Model
|
||||
from django.utils.encoding import smart_text
|
||||
|
||||
|
||||
def model_instance_diff(old, new, **kwargs):
|
||||
|
|
@ -11,9 +14,9 @@ def model_instance_diff(old, new, **kwargs):
|
|||
from auditlog.registry import auditlog
|
||||
|
||||
if not(old is None or isinstance(old, Model)):
|
||||
raise TypeError('The supplied old instance is not a valid model instance.')
|
||||
raise TypeError("The supplied old instance is not a valid model instance.")
|
||||
if not(new is None or isinstance(new, Model)):
|
||||
raise TypeError('The supplied new instance is not a valid model instance.')
|
||||
raise TypeError("The supplied new instance is not a valid model instance.")
|
||||
|
||||
diff = {}
|
||||
|
||||
|
|
@ -45,12 +48,12 @@ def model_instance_diff(old, new, **kwargs):
|
|||
|
||||
for field in fields:
|
||||
try:
|
||||
old_value = unicode(getattr(old, field.name, None))
|
||||
old_value = smart_text(getattr(old, field.name, None))
|
||||
except ObjectDoesNotExist:
|
||||
old_value = None
|
||||
|
||||
try:
|
||||
new_value = unicode(getattr(new, field.name, None))
|
||||
new_value = smart_text(getattr(new, field.name, None))
|
||||
except ObjectDoesNotExist:
|
||||
new_value = None
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import time
|
||||
|
||||
from django.conf import settings
|
||||
|
|
|
|||
|
|
@ -15,6 +15,5 @@ class Migration(migrations.Migration):
|
|||
model_name='logentry',
|
||||
name='object_id',
|
||||
field=models.BigIntegerField(db_index=True, null=True, verbose_name='object id', blank=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.contenttypes import generic
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db import models
|
||||
from django.utils.encoding import python_2_unicode_compatible, smart_text
|
||||
from django.utils.six import iteritems, integer_types
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
|
|
@ -23,9 +27,9 @@ class LogEntryManager(models.Manager):
|
|||
if changes is not None:
|
||||
kwargs.setdefault('content_type', ContentType.objects.get_for_model(instance))
|
||||
kwargs.setdefault('object_pk', pk)
|
||||
kwargs.setdefault('object_repr', str(instance))
|
||||
kwargs.setdefault('object_repr', smart_text(instance))
|
||||
|
||||
if isinstance(pk, (int, long)):
|
||||
if isinstance(pk, integer_types):
|
||||
kwargs.setdefault('object_id', pk)
|
||||
|
||||
# Delete log entries with the same pk as a newly created model. This should only be necessary when an pk is
|
||||
|
|
@ -50,7 +54,7 @@ class LogEntryManager(models.Manager):
|
|||
content_type = ContentType.objects.get_for_model(instance.__class__)
|
||||
pk = self._get_pk_value(instance)
|
||||
|
||||
if isinstance(pk, (int, long)):
|
||||
if isinstance(pk, integer_types):
|
||||
return self.filter(content_type=content_type, object_id=pk)
|
||||
else:
|
||||
return self.filter(content_type=content_type, object_pk=pk)
|
||||
|
|
@ -80,6 +84,7 @@ class LogEntryManager(models.Manager):
|
|||
return pk
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class LogEntry(models.Model):
|
||||
"""
|
||||
Represents an entry in the audit log. The content type is saved along with the textual and numeric (if available)
|
||||
|
|
@ -124,7 +129,7 @@ class LogEntry(models.Model):
|
|||
verbose_name = _("log entry")
|
||||
verbose_name_plural = _("log entries")
|
||||
|
||||
def __unicode__(self):
|
||||
def __str__(self):
|
||||
if self.action == self.Action.CREATE:
|
||||
fstring = _("Created {repr:s}")
|
||||
elif self.action == self.Action.UPDATE:
|
||||
|
|
@ -147,7 +152,7 @@ class LogEntry(models.Model):
|
|||
return {}
|
||||
|
||||
@property
|
||||
def changes_str(self, colon=': ', arrow=u' \u2192 ', separator='; '):
|
||||
def changes_str(self, colon=': ', arrow=smart_text(' \u2192 '), separator='; '):
|
||||
"""
|
||||
Return the changes recorded in this log entry as a string. The formatting of the string can be customized by
|
||||
setting alternate values for colon, arrow and separator. If the formatting is still not satisfying, please use
|
||||
|
|
@ -155,8 +160,8 @@ class LogEntry(models.Model):
|
|||
"""
|
||||
substrings = []
|
||||
|
||||
for field, values in self.changes_dict.iteritems():
|
||||
substring = u'{field_name:s}{colon:s}{old:s}{arrow:s}{new:s}'.format(
|
||||
for field, values in iteritems(self.changes_dict):
|
||||
substring = smart_text('{field_name:s}{colon:s}{old:s}{arrow:s}{new:s}').format(
|
||||
field_name=field,
|
||||
colon=colon,
|
||||
old=values[0],
|
||||
|
|
@ -196,5 +201,6 @@ class AuditlogHistoryField(generic.GenericRelation):
|
|||
try:
|
||||
from south.modelsinspector import add_introspection_rules
|
||||
add_introspection_rules([], ["^auditlog\.models\.AuditlogHistoryField"])
|
||||
raise DeprecationWarning("South support will be dropped in django-auditlog 0.4.0 or later.")
|
||||
except ImportError:
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
|
||||
from auditlog.diff import model_instance_diff
|
||||
from auditlog.models import LogEntry
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.db.models.signals import pre_save, post_save, post_delete
|
||||
from django.db.models import Model
|
||||
|
||||
|
||||
class AuditLogModelRegistry(object):
|
||||
class AuditlogModelRegistry(object):
|
||||
"""
|
||||
A registry that keeps track of the models that use Auditlog to track changes.
|
||||
"""
|
||||
|
||||
def __init__(self, create=True, update=True, delete=True, custom=None):
|
||||
from auditlog.receivers import log_create, log_update, log_delete
|
||||
|
||||
self._registry = {}
|
||||
self._signals = {}
|
||||
|
||||
|
|
@ -37,7 +39,7 @@ class AuditLogModelRegistry(object):
|
|||
}
|
||||
self._connect_signals(model)
|
||||
else:
|
||||
raise TypeError('Supplied model is not a valid model.')
|
||||
raise TypeError("Supplied model is not a valid model.")
|
||||
|
||||
def contains(self, model):
|
||||
"""
|
||||
|
|
@ -83,4 +85,11 @@ class AuditLogModelRegistry(object):
|
|||
'exclude_fields': self._registry[model]['exclude_fields'],
|
||||
}
|
||||
|
||||
auditlog = AuditLogModelRegistry()
|
||||
|
||||
class AuditLogModelRegistry(AuditlogModelRegistry):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(AuditLogModelRegistry, self).__init__(*args, **kwargs)
|
||||
raise DeprecationWarning("Use AuditlogModelRegistry instead of AuditLogModelRegistry, AuditLogModelRegistry will be removed in django-auditlog 0.4.0 or later.")
|
||||
|
||||
|
||||
auditlog = AuditlogModelRegistry()
|
||||
|
|
|
|||
|
|
@ -86,4 +86,4 @@ auditlog.register(SimpleModel)
|
|||
auditlog.register(AltPrimaryKeyModel)
|
||||
auditlog.register(ProxyModel)
|
||||
auditlog.register(SimpleIncludeModel, include_fields=['label', ])
|
||||
auditlog.register(SimpleExcludeModel, exclude_fields=['label', ])
|
||||
auditlog.register(SimpleExcludeModel, exclude_fields=['text', ])
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ class SimpeExcludeModelTest(TestCase):
|
|||
"""Log only changes that are not in exclude_fields"""
|
||||
|
||||
def test_register_exclude_fields(self):
|
||||
sem = SimpleIncludeModel(label='Exclude model', text='Looong text')
|
||||
sem = SimpleExcludeModel(label='Exclude model', text='Looong text')
|
||||
sem.save()
|
||||
self.assertTrue(sem.history.count() == 1, msg="There is one log entry")
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue