Skip to content

Instantly share code, notes, and snippets.

@ishakoktn
Forked from Bernix01/log.py
Last active March 16, 2021 23:40
Show Gist options
  • Save ishakoktn/08c04280cb14da6aac6dbb61ffe82260 to your computer and use it in GitHub Desktop.
Save ishakoktn/08c04280cb14da6aac6dbb61ffe82260 to your computer and use it in GitHub Desktop.
Using LogEntry on Django Rest Framework Viewset
'''
Extracted and modified from django-model-logging
It used it's own LogEntry model but since django
has it's own LogEntry maybe someone would want to
register in the same model instead of creating a
new one.
'''
from django.contrib.admin.models import LogEntry, ADDITION, CHANGE, ContentType, DELETION
from django.utils.translation import gettext as _
class LoggingMethodMixin:
"""
Adds methods that log changes made to users' data.
To use this, subclass it and ModelViewSet. Ensure
that the viewset you're mixing this into has `self.serializer_class`
attributes.
"""
def log(self, operation, instance, message=""):
LogEntry.objects.log_action(
user_id=self.request.user.id,
content_type_id=ContentType.objects.get_for_model(instance).pk,
object_id=instance.pk,
object_repr=str(instance),
action_flag=operation,
change_message=message
)
def _log_on_create(self, serializer):
"""Log the up-to-date serializer.data."""
self.log(operation=ADDITION, instance=serializer.instance)
def _log_on_update(self, serializer, old_data):
"""Log data from the updated serializer instance."""
diff = DeepDiff(old_data, serializer.data, ignore_order=True)
self.log(operation=CHANGE, instance=serializer.instance, message=diff)
def _log_on_destroy(self, instance):
"""Log data from the instance before it gets deleted."""
self.log(operation=DELETION, instance=instance)
class LoggingViewSetMixin(LoggingMethodMixin):
"""
A viewset that logs changes made to users' data.
To use this, subclass it and ModelViewSet. Ensure
that the viewset you're mixing this into has `self.serializer_class`
attributes.
If you modify any of the following methods, be sure to call super() or the
corresponding _log_on_X method:
- perform_create
- perform_update
- perform_destroy
"""
def perform_create(self, serializer):
"""Create an object and log its data."""
super().perform_create(serializer)
self._log_on_create(serializer)
def perform_update(self, serializer):
"""Update the instance and log the updated data."""
old_data = self.serializer_class(self.get_object()).data
super().perform_update(serializer)
self._log_on_update(serializer, old_data)
def perform_destroy(self, instance):
"""Delete the instance and log the deletion."""
super().perform_destroy(instance)
self._log_on_destroy(instance)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment