mirror of
https://github.com/jazzband/django-auditlog.git
synced 2026-03-16 22:20:26 +00:00
Merge branch 'master' into bugfix/changes-display-dict-errors
This commit is contained in:
commit
7fea1c59a1
8 changed files with 111 additions and 24 deletions
|
|
@ -21,6 +21,9 @@ env:
|
|||
- TOX_ENV=py35-django-111
|
||||
- TOX_ENV=py34-django-111
|
||||
- TOX_ENV=py27-django-111
|
||||
- TOX_ENV=py36-django-20
|
||||
- TOX_ENV=py35-django-20
|
||||
- TOX_ENV=py34-django-20
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ def get_field_value(obj, field):
|
|||
# to its naive form before we can accuratly compare them for changes.
|
||||
try:
|
||||
value = field.to_python(getattr(obj, field.name, None))
|
||||
if value is not None and settings.USE_TZ:
|
||||
if value is not None and settings.USE_TZ and not timezone.is_naive(value):
|
||||
value = timezone.make_naive(value, timezone=timezone.utc)
|
||||
except ObjectDoesNotExist:
|
||||
value = field.default if field.default is not NOT_PROVIDED else None
|
||||
|
|
|
|||
|
|
@ -70,14 +70,15 @@ class AuditlogMiddleware(MiddlewareMixin):
|
|||
Signal receiver with an extra, required 'user' kwarg. This method becomes a real (valid) signal receiver when
|
||||
it is curried with the actor.
|
||||
"""
|
||||
if signal_duid != threadlocal.auditlog['signal_duid']:
|
||||
return
|
||||
try:
|
||||
app_label, model_name = settings.AUTH_USER_MODEL.split('.')
|
||||
auth_user_model = apps.get_model(app_label, model_name)
|
||||
except ValueError:
|
||||
auth_user_model = apps.get_model('auth', 'user')
|
||||
if sender == LogEntry and isinstance(user, auth_user_model) and instance.actor is None:
|
||||
instance.actor = user
|
||||
if hasattr(threadlocal, 'auditlog'):
|
||||
if signal_duid != threadlocal.auditlog['signal_duid']:
|
||||
return
|
||||
try:
|
||||
app_label, model_name = settings.AUTH_USER_MODEL.split('.')
|
||||
auth_user_model = apps.get_model(app_label, model_name)
|
||||
except ValueError:
|
||||
auth_user_model = apps.get_model('auth', 'user')
|
||||
if sender == LogEntry and isinstance(user, auth_user_model) and instance.actor is None:
|
||||
instance.actor = user
|
||||
|
||||
instance.remote_addr = threadlocal.auditlog['remote_addr']
|
||||
|
|
|
|||
|
|
@ -23,7 +23,10 @@ class LogEntryAdminMixin(object):
|
|||
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])
|
||||
try:
|
||||
link = urlresolvers.reverse(viewname, args=[obj.actor.id])
|
||||
except NoReverseMatch:
|
||||
return u'%s' % (obj.actor)
|
||||
return u'<a href="%s">%s</a>' % (link, obj.actor)
|
||||
|
||||
return 'system'
|
||||
|
|
@ -34,7 +37,8 @@ class LogEntryAdminMixin(object):
|
|||
app_label, model = obj.content_type.app_label, obj.content_type.model
|
||||
viewname = 'admin:%s_%s_change' % (app_label, model)
|
||||
try:
|
||||
link = urlresolvers.reverse(viewname, args=[obj.object_id])
|
||||
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:
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ class DateTimeFieldModel(models.Model):
|
|||
timestamp = models.DateTimeField()
|
||||
date = models.DateField()
|
||||
time = models.TimeField()
|
||||
naive_dt = models.DateTimeField(null=True, blank=True)
|
||||
|
||||
history = AuditlogHistoryField()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""
|
||||
Settings file for the Auditlog test suite.
|
||||
"""
|
||||
import os
|
||||
import django
|
||||
|
||||
SECRET_KEY = 'test'
|
||||
|
|
@ -8,18 +9,27 @@ SECRET_KEY = 'test'
|
|||
INSTALLED_APPS = [
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.admin',
|
||||
'auditlog',
|
||||
'auditlog_tests',
|
||||
'multiselectfield',
|
||||
]
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
middlewares = (
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware'
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'auditlog.middleware.AuditlogMiddleware',
|
||||
)
|
||||
|
||||
if django.VERSION < (1, 10):
|
||||
MIDDLEWARE_CLASSES = middlewares
|
||||
else:
|
||||
MIDDLEWARE = middlewares
|
||||
|
||||
if django.VERSION <= (1, 9):
|
||||
POSTGRES_DRIVER = 'django.db.backends.postgresql_psycopg2'
|
||||
else:
|
||||
|
|
@ -42,6 +52,20 @@ DATABASES = {
|
|||
}
|
||||
}
|
||||
|
||||
ROOT_URLCONF = []
|
||||
TEMPLATES = [
|
||||
{
|
||||
'APP_DIRS': True,
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
]
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'auditlog_tests.urls'
|
||||
|
||||
USE_TZ = True
|
||||
|
|
|
|||
|
|
@ -270,12 +270,13 @@ class DateTimeFieldModelTest(TestCase):
|
|||
"""Tests if DateTimeField changes are recognised correctly"""
|
||||
|
||||
utc_plus_one = timezone.get_fixed_timezone(datetime.timedelta(hours=1))
|
||||
now = timezone.now()
|
||||
|
||||
def test_model_with_same_time(self):
|
||||
timestamp = datetime.datetime(2017, 1, 10, 12, 0, tzinfo=timezone.utc)
|
||||
date = datetime.date(2017, 1, 10)
|
||||
time = datetime.time(12, 0)
|
||||
dtm = DateTimeFieldModel(label='DateTimeField model', timestamp=timestamp, date=date, time=time)
|
||||
dtm = DateTimeFieldModel(label='DateTimeField model', timestamp=timestamp, date=date, time=time, naive_dt=self.now)
|
||||
dtm.save()
|
||||
self.assertTrue(dtm.history.count() == 1, msg="There is one log entry")
|
||||
|
||||
|
|
@ -293,7 +294,7 @@ class DateTimeFieldModelTest(TestCase):
|
|||
timestamp = datetime.datetime(2017, 1, 10, 12, 0, tzinfo=timezone.utc)
|
||||
date = datetime.date(2017, 1, 10)
|
||||
time = datetime.time(12, 0)
|
||||
dtm = DateTimeFieldModel(label='DateTimeField model', timestamp=timestamp, date=date, time=time)
|
||||
dtm = DateTimeFieldModel(label='DateTimeField model', timestamp=timestamp, date=date, time=time, naive_dt=self.now)
|
||||
dtm.save()
|
||||
self.assertTrue(dtm.history.count() == 1, msg="There is one log entry")
|
||||
|
||||
|
|
@ -309,7 +310,7 @@ class DateTimeFieldModelTest(TestCase):
|
|||
timestamp = datetime.datetime(2017, 1, 10, 12, 0, tzinfo=timezone.utc)
|
||||
date = datetime.date(2017, 1, 10)
|
||||
time = datetime.time(12, 0)
|
||||
dtm = DateTimeFieldModel(label='DateTimeField model', timestamp=timestamp, date=date, time=time)
|
||||
dtm = DateTimeFieldModel(label='DateTimeField model', timestamp=timestamp, date=date, time=time, naive_dt=self.now)
|
||||
dtm.save()
|
||||
self.assertTrue(dtm.history.count() == 1, msg="There is one log entry")
|
||||
|
||||
|
|
@ -325,7 +326,7 @@ class DateTimeFieldModelTest(TestCase):
|
|||
timestamp = datetime.datetime(2017, 1, 10, 12, 0, tzinfo=timezone.utc)
|
||||
date = datetime.date(2017, 1, 10)
|
||||
time = datetime.time(12, 0)
|
||||
dtm = DateTimeFieldModel(label='DateTimeField model', timestamp=timestamp, date=date, time=time)
|
||||
dtm = DateTimeFieldModel(label='DateTimeField model', timestamp=timestamp, date=date, time=time, naive_dt=self.now)
|
||||
dtm.save()
|
||||
self.assertTrue(dtm.history.count() == 1, msg="There is one log entry")
|
||||
|
||||
|
|
@ -341,7 +342,7 @@ class DateTimeFieldModelTest(TestCase):
|
|||
timestamp = datetime.datetime(2017, 1, 10, 12, 0, tzinfo=timezone.utc)
|
||||
date = datetime.date(2017, 1, 10)
|
||||
time = datetime.time(12, 0)
|
||||
dtm = DateTimeFieldModel(label='DateTimeField model', timestamp=timestamp, date=date, time=time)
|
||||
dtm = DateTimeFieldModel(label='DateTimeField model', timestamp=timestamp, date=date, time=time, naive_dt=self.now)
|
||||
dtm.save()
|
||||
self.assertTrue(dtm.history.count() == 1, msg="There is one log entry")
|
||||
|
||||
|
|
@ -357,7 +358,7 @@ class DateTimeFieldModelTest(TestCase):
|
|||
timestamp = datetime.datetime(2017, 1, 10, 12, 0, tzinfo=timezone.utc)
|
||||
date = datetime.date(2017, 1, 10)
|
||||
time = datetime.time(12, 0)
|
||||
dtm = DateTimeFieldModel(label='DateTimeField model', timestamp=timestamp, date=date, time=time)
|
||||
dtm = DateTimeFieldModel(label='DateTimeField model', timestamp=timestamp, date=date, time=time, naive_dt=self.now)
|
||||
dtm.save()
|
||||
self.assertTrue(dtm.history.count() == 1, msg="There is one log entry")
|
||||
|
||||
|
|
@ -373,7 +374,7 @@ class DateTimeFieldModelTest(TestCase):
|
|||
timestamp = datetime.datetime(2017, 1, 10, 15, 0, tzinfo=timezone.utc)
|
||||
date = datetime.date(2017, 1, 10)
|
||||
time = datetime.time(12, 0)
|
||||
dtm = DateTimeFieldModel(label='DateTimeField model', timestamp=timestamp, date=date, time=time)
|
||||
dtm = DateTimeFieldModel(label='DateTimeField model', timestamp=timestamp, date=date, time=time, naive_dt=self.now)
|
||||
dtm.save()
|
||||
localized_timestamp = timestamp.astimezone(gettz(settings.TIME_ZONE))
|
||||
self.assertTrue(dtm.history.latest().changes_display_dict["timestamp"][1] == \
|
||||
|
|
@ -401,7 +402,7 @@ class DateTimeFieldModelTest(TestCase):
|
|||
timestamp = datetime.datetime(2017, 1, 10, 15, 0, tzinfo=timezone.utc)
|
||||
date = datetime.date(2017, 1, 10)
|
||||
time = datetime.time(12, 0)
|
||||
dtm = DateTimeFieldModel(label='DateTimeField model', timestamp=timestamp, date=date, time=time)
|
||||
dtm = DateTimeFieldModel(label='DateTimeField model', timestamp=timestamp, date=date, time=time, naive_dt=self.now)
|
||||
dtm.save()
|
||||
self.assertTrue(dtm.history.latest().changes_display_dict["date"][1] == \
|
||||
dateformat.format(date, settings.DATE_FORMAT),
|
||||
|
|
@ -426,7 +427,7 @@ class DateTimeFieldModelTest(TestCase):
|
|||
timestamp = datetime.datetime(2017, 1, 10, 15, 0, tzinfo=timezone.utc)
|
||||
date = datetime.date(2017, 1, 10)
|
||||
time = datetime.time(12, 0)
|
||||
dtm = DateTimeFieldModel(label='DateTimeField model', timestamp=timestamp, date=date, time=time)
|
||||
dtm = DateTimeFieldModel(label='DateTimeField model', timestamp=timestamp, date=date, time=time, naive_dt=self.now)
|
||||
dtm.save()
|
||||
self.assertTrue(dtm.history.latest().changes_display_dict["time"][1] == \
|
||||
dateformat.format(time, settings.TIME_FORMAT),
|
||||
|
|
@ -447,6 +448,17 @@ class DateTimeFieldModelTest(TestCase):
|
|||
msg=("The time should be formatted according to Django's settings for"
|
||||
" USE_L10N is True with a different LANGUAGE_CODE."))
|
||||
|
||||
def test_update_naive_dt(self):
|
||||
timestamp = datetime.datetime(2017, 1, 10, 15, 0, tzinfo=timezone.utc)
|
||||
date = datetime.date(2017, 1, 10)
|
||||
time = datetime.time(12, 0)
|
||||
dtm = DateTimeFieldModel(label='DateTimeField model', timestamp=timestamp, date=date, time=time, naive_dt=self.now)
|
||||
dtm.save()
|
||||
|
||||
# Change with naive field doesnt raise error
|
||||
dtm.naive_dt = timezone.make_naive(timezone.now(), timezone=timezone.utc)
|
||||
dtm.save()
|
||||
|
||||
|
||||
class UnregisterTest(TestCase):
|
||||
def setUp(self):
|
||||
|
|
@ -622,3 +634,32 @@ class CompatibilityTest(TestCase):
|
|||
else:
|
||||
assert not self.user.is_anonymous
|
||||
assert compat.is_authenticated(self.user)
|
||||
|
||||
|
||||
class AdminPanelTest(TestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.username = "test_admin"
|
||||
cls.password = User.objects.make_random_password()
|
||||
cls.user, created = User.objects.get_or_create(username=cls.username)
|
||||
cls.user.set_password(cls.password)
|
||||
cls.user.is_staff = True
|
||||
cls.user.is_superuser = True
|
||||
cls.user.is_active = True
|
||||
cls.user.save()
|
||||
cls.obj = SimpleModel.objects.create(text='For admin logentry test')
|
||||
|
||||
def test_auditlog_admin(self):
|
||||
self.client.login(username=self.username, password=self.password)
|
||||
log_pk = self.obj.history.latest().pk
|
||||
res = self.client.get("/admin/auditlog/logentry/")
|
||||
assert res.status_code == 200
|
||||
res = self.client.get("/admin/auditlog/logentry/add/")
|
||||
assert res.status_code == 200
|
||||
res = self.client.get("/admin/auditlog/logentry/{}/".format(log_pk), follow=True)
|
||||
assert res.status_code == 200
|
||||
res = self.client.get("/admin/auditlog/logentry/{}/delete/".format(log_pk))
|
||||
assert res.status_code == 200
|
||||
res = self.client.get("/admin/auditlog/logentry/{}/history/".format(log_pk))
|
||||
assert res.status_code == 200
|
||||
|
||||
|
|
|
|||
13
src/auditlog_tests/urls.py
Normal file
13
src/auditlog_tests/urls.py
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import django
|
||||
from django.conf.urls import include, url
|
||||
from django.contrib import admin
|
||||
|
||||
|
||||
if django.VERSION < (1, 9):
|
||||
admin_urls = include(admin.site.urls)
|
||||
else:
|
||||
admin_urls = admin.site.urls
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^admin/', admin_urls),
|
||||
]
|
||||
Loading…
Reference in a new issue