Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore null changeset on creation and deletion #282

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 25 additions & 11 deletions auditlog/diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Model, NOT_PROVIDED, DateTimeField
from django.utils import timezone
from django.utils.encoding import smart_text
from django.utils.encoding import smart_str


def track_field(field):
Expand All @@ -17,12 +17,16 @@ def track_field(field):
:rtype: bool
"""
from auditlog.models import LogEntry

# Do not track many to many relations
if field.many_to_many:
return False

# Do not track relations to LogEntry
if getattr(field, 'remote_field', None) is not None and field.remote_field.model == LogEntry:
if (
getattr(field, "remote_field", None) is not None
and field.remote_field.model == LogEntry
):
return False

return True
Expand Down Expand Up @@ -65,7 +69,7 @@ def get_field_value(obj, field):
value = field.default if field.default is not NOT_PROVIDED else None
else:
try:
value = smart_text(getattr(obj, field.name, None))
value = smart_str(getattr(obj, field.name, None))
except ObjectDoesNotExist:
value = field.default if field.default is not NOT_PROVIDED else None

Expand Down Expand Up @@ -108,24 +112,34 @@ def model_instance_diff(old, new):
model_fields = None

# Check if fields must be filtered
if model_fields and (model_fields['include_fields'] or model_fields['exclude_fields']) and fields:
if (
model_fields
and (model_fields["include_fields"] or model_fields["exclude_fields"])
and fields
):
filtered_fields = []
if model_fields['include_fields']:
filtered_fields = [field for field in fields
if field.name in model_fields['include_fields']]
if model_fields["include_fields"]:
filtered_fields = [
field
for field in fields
if field.name in model_fields["include_fields"]
]
else:
filtered_fields = fields
if model_fields['exclude_fields']:
filtered_fields = [field for field in filtered_fields
if field.name not in model_fields['exclude_fields']]
if model_fields["exclude_fields"]:
filtered_fields = [
field
for field in filtered_fields
if field.name not in model_fields["exclude_fields"]
]
fields = filtered_fields

for field in fields:
old_value = get_field_value(old, field)
new_value = get_field_value(new, field)

if old_value != new_value:
diff[field.name] = (smart_text(old_value), smart_text(new_value))
diff[field.name] = (smart_str(old_value), smart_str(new_value))

if len(diff) == 0:
diff = None
Expand Down
24 changes: 14 additions & 10 deletions auditlog/receivers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ def log_create(sender, instance, created, **kwargs):
if created:
changes = model_instance_diff(None, instance)

log_entry = LogEntry.objects.log_create(
instance,
action=LogEntry.Action.CREATE,
changes=json.dumps(changes),
)
# Log an entry only if there are changes
if changes:
log_entry = LogEntry.objects.log_create(
instance,
action=LogEntry.Action.CREATE,
changes=json.dumps(changes),
)


def log_update(sender, instance, **kwargs):
Expand Down Expand Up @@ -54,8 +56,10 @@ def log_delete(sender, instance, **kwargs):
if instance.pk is not None:
changes = model_instance_diff(instance, None)

log_entry = LogEntry.objects.log_create(
instance,
action=LogEntry.Action.DELETE,
changes=json.dumps(changes),
)
# Log an entry only if there are changes
if changes:
log_entry = LogEntry.objects.log_create(
instance,
action=LogEntry.Action.DELETE,
changes=json.dumps(changes),
)
2 changes: 1 addition & 1 deletion auditlog_tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class SimpleIncludeModel(models.Model):
A simple model used for register's include_fields kwarg
"""

label = models.CharField(max_length=100)
label = models.CharField(null=True, max_length=100)
text = models.TextField(blank=True)

history = AuditlogHistoryField()
Expand Down
14 changes: 14 additions & 0 deletions auditlog_tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,20 @@ def test_register_include_fields(self):
sim.save()
self.assertTrue(sim.history.count() == 2, msg="There are two log entries")

# Create with text, ignore
sim = SimpleIncludeModel(text="Looong text")
sim.save()
self.assertTrue(sim.history.count() == 0, msg="There are no log entries")

# Delete, ignore
self.assertTrue(
LogEntry.objects.count() == 2, msg="There are two log entries total"
)
sim.delete()
self.assertTrue(
LogEntry.objects.count() == 2, msg="No log entry added after delete"
)


class SimpeExcludeModelTest(TestCase):
"""Log only changes that are not in exclude_fields"""
Expand Down