mirror of
https://github.com/jazzband/django-auditlog.git
synced 2026-03-16 22:20:26 +00:00
commit
ed055d93bc
2 changed files with 54 additions and 10 deletions
|
|
@ -9,3 +9,4 @@ install:
|
|||
- "pip install -r requirements.txt"
|
||||
- "pip install Django==$DJANGO_VERSION"
|
||||
script: "python src/runtests.py"
|
||||
sudo: false
|
||||
|
|
|
|||
|
|
@ -1,15 +1,58 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db.models import Model
|
||||
from django.db.models import Model, NOT_PROVIDED
|
||||
from django.utils.encoding import smart_text
|
||||
|
||||
|
||||
def track_field(field):
|
||||
"""
|
||||
Returns whether the given field should be tracked by Auditlog.
|
||||
|
||||
Untracked fields are many-to-many relations and relations to the Auditlog LogEntry model.
|
||||
|
||||
:param field: The field to check.
|
||||
:type field: Field
|
||||
:return: Whether the given field should be tracked.
|
||||
: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, 'rel', None) is not None and field.rel.to == LogEntry:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def get_fields_in_model(instance):
|
||||
"""
|
||||
Returns the list of fields in the given model instance. Checks whether to use the official _meta API or use the raw
|
||||
data. This method excludes many to many fields.
|
||||
|
||||
:param instance: The model instance to get the fields for
|
||||
:type instance: Model
|
||||
:return: The list of fields for the given model (instance)
|
||||
:rtype: list
|
||||
"""
|
||||
assert isinstance(instance, Model)
|
||||
|
||||
# Check if the Django 1.8 _meta API is available
|
||||
use_api = hasattr(instance._meta, 'get_fields') and callable(instance._meta.get_fields)
|
||||
|
||||
if use_api:
|
||||
return [f for f in instance._meta.get_fields() if track_field(f)]
|
||||
return instance._meta.fields
|
||||
|
||||
|
||||
def model_instance_diff(old, new, **kwargs):
|
||||
"""
|
||||
Calculate the differences between two model instances. One of the instances may be None (i.e., a newly
|
||||
created model or deleted model). This will cause all fields with a value to have changed (from None).
|
||||
|
||||
created model or deleted model). This will cause all fields with a value to have changed (from the fields default
|
||||
value).
|
||||
"""
|
||||
from auditlog.registry import auditlog
|
||||
|
||||
|
|
@ -21,13 +64,13 @@ def model_instance_diff(old, new, **kwargs):
|
|||
diff = {}
|
||||
|
||||
if old is not None and new is not None:
|
||||
fields = set(old._meta.fields + new._meta.fields)
|
||||
fields = set(get_fields_in_model(old) + get_fields_in_model(new))
|
||||
model_fields = auditlog.get_model_fields(new._meta.model)
|
||||
elif old is not None:
|
||||
fields = set(old._meta.fields)
|
||||
fields = set(get_fields_in_model(old))
|
||||
model_fields = auditlog.get_model_fields(old._meta.model)
|
||||
elif new is not None:
|
||||
fields = set(new._meta.fields)
|
||||
fields = set(get_fields_in_model(new))
|
||||
model_fields = auditlog.get_model_fields(new._meta.model)
|
||||
else:
|
||||
fields = set()
|
||||
|
|
@ -48,17 +91,17 @@ def model_instance_diff(old, new, **kwargs):
|
|||
|
||||
for field in fields:
|
||||
try:
|
||||
old_value = smart_text(getattr(old, field.name, None))
|
||||
old_value = getattr(old, field.name, None)
|
||||
except ObjectDoesNotExist:
|
||||
old_value = None
|
||||
old_value = field.default if field.default is not NOT_PROVIDED else None
|
||||
|
||||
try:
|
||||
new_value = smart_text(getattr(new, field.name, None))
|
||||
new_value = getattr(new, field.name, None)
|
||||
except ObjectDoesNotExist:
|
||||
new_value = None
|
||||
|
||||
if old_value != new_value:
|
||||
diff[field.name] = (old_value, new_value)
|
||||
diff[field.name] = (smart_text(old_value), smart_text(new_value))
|
||||
|
||||
if len(diff) == 0:
|
||||
diff = None
|
||||
|
|
|
|||
Loading…
Reference in a new issue