django-auditlog/src/auditlog/mixins.py

70 lines
2.4 KiB
Python
Raw Normal View History

2016-09-02 19:02:42 +00:00
import json
from django.conf import settings
Add Django 2.0 Support (#154) * Add changes for django 2.0 Made the following changes to ensure compatibility with django 2.0: 1. Replaced function calls to `is_authenticated()` with reference to property `is_authenticated`. 2. Added try/except call to import `django.core.urlresolvers` (now called `django.urls`. Also added an `... as ...` statement to ensure that references in the code to `urlresolvers` don't need to be changed. 3. Fixed calls statement of `on_delete` arg to all ForeignKey fields. Note that previously a kwarg was acceptable, but this is now a positional arg, and the selected `on_delete` method has been retained. * Update tox tests and consequentual changes Updated tox.ini to also test django 2.0 on python 3+. Some changes made to previous commits required to ensure all tests passed: - Added `compat.py` to have a `is_authenticated()` function to check authentication. This was necessary as the property/method call for `is_authenticated` is no compatible between django 1.8 (LTS) and 2.0. Changed AuditLogMiddleware to call this compatibility function instead of the django built-ins as a result. - Changes made to `auditlog/models.py` to apply kwargs to both `to=` and `on_delete=` for consistency of handling in all version tested. Incorrect django version specified for tox.ini. Now fixed. * Add 'on_delete' kwarg to initial migration Added and re-arranged 'on_delete' and 'to' kwargs in initial migration to ensure compatbility with later versions of Django. Also included updated manifest with changes required due to django 2.0 work. * Add TestCase for compat.py Added simple test case for compat.py file. * Changes follow code review 2017-12-21 * More changes following code review 2017-12-28 1. Added detailed commentary to `compat.py` to ensure reason why `is_authenticated()` compatibility function is needed 2. Changed `hasattr` to `callable` in compat.is_authenticated() 3. Fixed typo in migration 0001 to use correct `on_delete` function
2018-01-02 18:50:45 +00:00
try:
from django.core import urlresolvers
except ImportError:
from django import urls as urlresolvers
2017-02-16 21:24:24 +00:00
try:
from django.urls.exceptions import NoReverseMatch
except ImportError:
from django.core.urlresolvers import NoReverseMatch
2016-09-02 19:02:42 +00:00
MAX = 75
class LogEntryAdminMixin(object):
def created(self, obj):
return obj.timestamp.strftime('%Y-%m-%d %H:%M:%S')
created.short_description = 'Created'
def user_url(self, obj):
if obj.actor:
app_label, model = settings.AUTH_USER_MODEL.split('.')
viewname = 'admin:%s_%s_change' % (app_label, model.lower())
link = urlresolvers.reverse(viewname, args=[obj.actor.id])
return u'<a href="%s">%s</a>' % (link, obj.actor)
2016-09-02 19:02:42 +00:00
return 'system'
user_url.allow_tags = True
user_url.short_description = 'User'
def resource_url(self, obj):
app_label, model = obj.content_type.app_label, obj.content_type.model
viewname = 'admin:%s_%s_change' % (app_label, model)
try:
args = [obj.object_pk] if obj.object_id is None else [obj.object_id]
link = urlresolvers.reverse(viewname, args=args)
except NoReverseMatch:
return obj.object_repr
else:
return u'<a href="%s">%s</a>' % (link, obj.object_repr)
2016-09-02 19:02:42 +00:00
resource_url.allow_tags = True
resource_url.short_description = 'Resource'
def msg_short(self, obj):
if obj.action == 2:
return '' # delete
changes = json.loads(obj.changes)
s = '' if len(changes) == 1 else 's'
fields = ', '.join(changes.keys())
if len(fields) > MAX:
i = fields.rfind(' ', 0, MAX)
fields = fields[:i] + ' ..'
return '%d change%s: %s' % (len(changes), s, fields)
msg_short.short_description = 'Changes'
def msg(self, obj):
if obj.action == 2:
return '' # delete
changes = json.loads(obj.changes)
msg = '<table><tr><th>#</th><th>Field</th><th>From</th><th>To</th></tr>'
for i, field in enumerate(sorted(changes), 1):
value = [i, field] + (['***', '***'] if field == 'password' else changes[field])
msg += '<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>' % tuple(value)
msg += '</table>'
return msg
msg.allow_tags = True
msg.short_description = 'Changes'