Changed registry from list to dictionary and use register kwargs to track fields that must be changed or excluded

This commit is contained in:
Vittorio Zamboni 2014-10-03 15:13:03 +02:00
parent 7501363487
commit 4ae09eb8b4
4 changed files with 43 additions and 11 deletions

View file

@ -1,11 +1,14 @@
from django.db.models import Model
def model_instance_diff(old, new):
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).
"""
from auditlog.registry import auditlog
if not(old is None or isinstance(old, Model)):
raise TypeError('The supplied old instance is not a valid model instance.')
if not(new is None or isinstance(new, Model)):
@ -15,13 +18,29 @@ def model_instance_diff(old, new):
if old is not None and new is not None:
fields = set(old._meta.fields + new._meta.fields)
model_fields = auditlog.get_model_fields(new._meta.model)
elif old is not None:
fields = set(old._meta.fields)
model_fields = auditlog.get_model_fields(old._meta.model)
elif new is not None:
fields = set(new._meta.fields)
model_fields = auditlog.get_model_fields(new._meta.model)
else:
fields = set()
# Check if fields must be filtered
if (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']]
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']]
fields = filtered_fields
for field in fields:
old_value = unicode(getattr(old, field.name, None))
new_value = unicode(getattr(new, field.name, None))

View file

@ -38,7 +38,7 @@ class LogEntryManager(models.Manager):
return self.create(**kwargs)
return None
def get_for_object(self, instance):
"""
Get log entries for the specified object.
@ -152,7 +152,7 @@ class LogEntry(models.Model):
substrings.append(substring)
return separator.join(substrings)
class AuditlogHistoryField(generic.GenericRelation):
"""

View file

@ -7,7 +7,7 @@ def log_create(sender, instance, created, **kwargs):
"""
Signal receiver that creates a log entry when a model instance is first saved to the database.
Direct use is discouraged, connect your model through auditlog.registry.registry instead.
Direct use is discouraged, connect your model through auditlog.registry.register instead.
"""
if created:
changes = model_instance_diff(None, instance)
@ -23,7 +23,7 @@ def log_update(sender, instance, **kwargs):
"""
Signal receiver that creates a log entry when a model instance is changed and saved to the database.
Direct use is discouraged, connect your model through auditlog.registry.registry instead.
Direct use is discouraged, connect your model through auditlog.registry.register instead.
"""
if instance.pk is not None:
try:
@ -48,7 +48,7 @@ def log_delete(sender, instance, **kwargs):
"""
Signal receiver that creates a log entry when a model instance is deleted from the database.
Direct use is discouraged, connect your model through auditlog.registry.registry instead.
Direct use is discouraged, connect your model through auditlog.registry.register instead.
"""
if instance.pk is not None:
changes = model_instance_diff(instance, None)

View file

@ -1,6 +1,5 @@
from django.db.models.signals import pre_save, post_save, post_delete
from django.db.models import Model
from auditlog.receivers import log_create, log_update, log_delete
class AuditLogModelRegistry(object):
@ -9,7 +8,8 @@ class AuditLogModelRegistry(object):
"""
def __init__(self, create=True, update=True, delete=True, custom=None):
self._registry = []
from auditlog.receivers import log_create, log_update, log_delete
self._registry = {}
self._signals = {}
if create:
@ -22,15 +22,23 @@ class AuditLogModelRegistry(object):
if custom is not None:
self._signals.update(custom)
def register(self, model):
def register(self, model, **kwargs):
"""
Register a model with auditlog. Auditlog will then track mutations on this model's instances.
Kwargs:
- `include_fields`: list of field names to include in diff
- `exclude_fields`: list of field names to exclude in diff
"""
if issubclass(model, Model):
self._registry.append(model)
self._registry[model] = {
'include_fields': kwargs.get('include_fields', []),
'exclude_fields': kwargs.get('exclude_fields', []),
}
self._connect_signals(model)
else:
raise TypeError('Supplied model is not a valid model.')
print self._registry
def contains(self, model):
"""
@ -43,7 +51,7 @@ class AuditLogModelRegistry(object):
Unregister a model with auditlog. This will not affect the database.
"""
try:
self._registry.pop(model)
del self._registry[model]
except KeyError:
pass
else:
@ -70,5 +78,10 @@ class AuditLogModelRegistry(object):
"""
return (self.__class__, model, signal)
def get_model_fields(self, model):
return {
'include_fields': self._registry[model]['include_fields'],
'exclude_fields': self._registry[model]['exclude_fields'],
}
auditlog = AuditLogModelRegistry()