From b7aa3e1b2c451a92f45485558c76186b885ffb29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alieh=20Ryma=C5=A1e=C5=ADski?= Date: Mon, 1 Aug 2022 15:01:09 +0000 Subject: [PATCH 1/2] Display timestamps in server timezone --- CHANGELOG.md | 4 ++++ auditlog/mixins.py | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47436fe6..83c7c6ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes +#### Fixes + +- fix: Display `created` timestamp in server timezone ([#404](https://github.com/jazzband/django-auditlog/pull/404)) + ## 2.1.1 (2022-07-27) #### Improvements diff --git a/auditlog/mixins.py b/auditlog/mixins.py index 6b045722..2d16e1a0 100644 --- a/auditlog/mixins.py +++ b/auditlog/mixins.py @@ -5,6 +5,7 @@ from django.urls.exceptions import NoReverseMatch from django.utils.html import format_html, format_html_join from django.utils.safestring import mark_safe +from django.utils.timezone import localtime from auditlog.models import LogEntry @@ -13,7 +14,7 @@ class LogEntryAdminMixin: def created(self, obj): - return obj.timestamp.strftime("%Y-%m-%d %H:%M:%S") + return localtime(obj.timestamp).strftime("%Y-%m-%d %H:%M:%S") created.short_description = "Created" From 8d7b3d2c9da7311362d3d7a00f6931f1952b5595 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alieh=20Ryma=C5=A1e=C5=ADski?= Date: Mon, 1 Aug 2022 16:54:57 +0000 Subject: [PATCH 2/2] Add tests for created timestamps --- auditlog_tests/tests.py | 44 +++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/auditlog_tests/tests.py b/auditlog_tests/tests.py index a79b0db1..d5f1171c 100644 --- a/auditlog_tests/tests.py +++ b/auditlog_tests/tests.py @@ -4,6 +4,7 @@ import warnings from unittest import mock +import freezegun from dateutil.tz import gettz from django.apps import apps from django.conf import settings @@ -1233,31 +1234,40 @@ def test_changes_display_dict_arrayfield(self): 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 setUp(self): + self.user = User.objects.create_user( + username="test_admin", is_staff=True, is_superuser=True, is_active=True + ) + self.site = AdminSite() + self.admin = LogEntryAdmin(LogEntry, self.site) + with freezegun.freeze_time("2022-08-01 12:00:00Z"): + self.obj = SimpleModel.objects.create(text="For admin logentry test") def test_auditlog_admin(self): - self.client.login(username=self.username, password=self.password) + self.client.force_login(self.user) log_pk = self.obj.history.latest().pk res = self.client.get("/admin/auditlog/logentry/") - assert res.status_code == 200 + self.assertEqual(res.status_code, 200) res = self.client.get("/admin/auditlog/logentry/add/") - assert res.status_code == 403 + self.assertEqual(res.status_code, 403) res = self.client.get(f"/admin/auditlog/logentry/{log_pk}/", follow=True) - assert res.status_code == 200 + self.assertEqual(res.status_code, 200) res = self.client.get(f"/admin/auditlog/logentry/{log_pk}/delete/") - assert res.status_code == 200 + self.assertEqual(res.status_code, 200) res = self.client.get(f"/admin/auditlog/logentry/{log_pk}/history/") - assert res.status_code == 200 + self.assertEqual(res.status_code, 200) + + def test_created_timezone(self): + log_entry = self.obj.history.latest() + + for tz, timestamp in [ + ("UTC", "2022-08-01 12:00:00"), + ("Asia/Tbilisi", "2022-08-01 16:00:00"), + ("America/Buenos_Aires", "2022-08-01 09:00:00"), + ("Asia/Kathmandu", "2022-08-01 17:45:00"), + ]: + with self.settings(TIME_ZONE=tz): + self.assertEqual(self.admin.created(log_entry), timestamp) class DiffMsgTest(TestCase):