Skip to content

Commit

Permalink
Added verbose field name in admin (#428)
Browse files Browse the repository at this point in the history
Co-authored-by: Hasan Ramezani <hasan.r67@gmail.com>
  • Loading branch information
rptmat57 and hramezani authored Sep 20, 2022
1 parent fb90112 commit d74c118
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#### Improvements

- feat: Add `serialized_data` field on `LogEntry` model. ([#412](https://github.com/jazzband/django-auditlog/pull/412))
- feat: Display the field name as it would be displayed in Django Admin or use `mapping_field` if available [#428](https://github.com/jazzband/django-auditlog/pull/428)

#### Fixes

Expand Down
25 changes: 23 additions & 2 deletions auditlog/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

from django import urls as urlresolvers
from django.conf import settings
from django.core.exceptions import FieldDoesNotExist
from django.forms.utils import pretty_name
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
from auditlog.registry import auditlog

MAX = 75

Expand Down Expand Up @@ -81,7 +84,9 @@ def msg(self, obj):
msg.append("<table>")
msg.append(self._format_header("#", "Field", "From", "To"))
for i, (field, change) in enumerate(sorted(atom_changes.items()), 1):
value = [i, field] + (["***", "***"] if field == "password" else change)
value = [i, self.field_verbose_name(obj, field)] + (
["***", "***"] if field == "password" else change
)
msg.append(self._format_line(*value))
msg.append("</table>")

Expand All @@ -99,7 +104,7 @@ def msg(self, obj):
format_html(
"<tr><td>{}</td><td>{}</td><td>{}</td><td>{}</td></tr>",
i,
field,
self.field_verbose_name(obj, field),
change["operation"],
change_html,
)
Expand All @@ -120,3 +125,19 @@ def _format_line(self, *values):
return format_html(
"".join(["<tr>", "<td>{}</td>" * len(values), "</tr>"]), *values
)

def field_verbose_name(self, obj, field_name: str):
model = obj.content_type.model_class()
try:
model_fields = auditlog.get_model_fields(model._meta.model)
mapping_field_name = model_fields["mapping_fields"].get(field_name)
if mapping_field_name:
return mapping_field_name
except KeyError:
# Model definition in auditlog was probably removed
pass
try:
field = model._meta.get_field(field_name)
return pretty_name(getattr(field, "verbose_name", field_name))
except FieldDoesNotExist:
return pretty_name(field_name)
40 changes: 33 additions & 7 deletions auditlog_tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1323,8 +1323,8 @@ def test_changes_msg_delete(self):
(
"<table>"
"<tr><th>#</th><th>Field</th><th>From</th><th>To</th></tr>"
"<tr><td>1</td><td>field one</td><td>value before deletion</td><td>None</td></tr>"
"<tr><td>2</td><td>field two</td><td>11</td><td>None</td></tr>"
"<tr><td>1</td><td>Field one</td><td>value before deletion</td><td>None</td></tr>"
"<tr><td>2</td><td>Field two</td><td>11</td><td>None</td></tr>"
"</table>"
),
)
Expand All @@ -1346,8 +1346,8 @@ def test_changes_msg_create(self):
(
"<table>"
"<tr><th>#</th><th>Field</th><th>From</th><th>To</th></tr>"
"<tr><td>1</td><td>field one</td><td>None</td><td>a value</td></tr>"
"<tr><td>2</td><td>field two</td><td>None</td><td>11</td></tr>"
"<tr><td>1</td><td>Field one</td><td>None</td><td>a value</td></tr>"
"<tr><td>2</td><td>Field two</td><td>None</td><td>11</td></tr>"
"</table>"
),
)
Expand All @@ -1369,9 +1369,9 @@ def test_changes_msg_update(self):
(
"<table>"
"<tr><th>#</th><th>Field</th><th>From</th><th>To</th></tr>"
"<tr><td>1</td><td>field one</td><td>old value of field one</td>"
"<tr><td>1</td><td>Field one</td><td>old value of field one</td>"
"<td>new value of field one</td></tr>"
"<tr><td>2</td><td>field two</td><td>11</td><td>42</td></tr>"
"<tr><td>2</td><td>Field two</td><td>11</td><td>42</td></tr>"
"</table>"
),
)
Expand All @@ -1394,12 +1394,38 @@ def test_changes_msg_m2m(self):
(
"<table>"
"<tr><th>#</th><th>Relationship</th><th>Action</th><th>Objects</th></tr>"
"<tr><td>1</td><td>some_m2m_field</td><td>add</td><td>Example User (user 1)"
"<tr><td>1</td><td>Some m2m field</td><td>add</td><td>Example User (user 1)"
"<br>Illustration (user 42)</td></tr>"
"</table>"
),
)

def test_unregister_after_log(self):
log_entry = self._create_log_entry(
LogEntry.Action.CREATE,
{
"field two": [None, 11],
"field one": [None, "a value"],
},
)
# Unregister
auditlog.unregister(SimpleModel)
self.assertEqual(
self.admin.msg_short(log_entry), "2 changes: field two, field one"
)
self.assertEqual(
self.admin.msg(log_entry),
(
"<table>"
"<tr><th>#</th><th>Field</th><th>From</th><th>To</th></tr>"
"<tr><td>1</td><td>Field one</td><td>None</td><td>a value</td></tr>"
"<tr><td>2</td><td>Field two</td><td>None</td><td>11</td></tr>"
"</table>"
),
)
# Re-register
auditlog.register(SimpleModel)


class NoDeleteHistoryTest(TestCase):
def test_delete_related(self):
Expand Down

0 comments on commit d74c118

Please sign in to comment.