Skip to content

Instantly share code, notes, and snippets.

@klebercode
Forked from ahmontero/actions.py
Created February 8, 2019 01:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save klebercode/4bebf9f13a56bf2ae8704b37f8dab80a to your computer and use it in GitHub Desktop.
Save klebercode/4bebf9f13a56bf2ae8704b37f8dab80a to your computer and use it in GitHub Desktop.
Trace the changes made to a django model. You can see how to use it in example.py
# -*- encoding: utf-8 -*-
# --------------------------
# Ripped from django project
# --------------------------
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import ugettext as _
from django.utils.encoding import force_unicode
def log_addition(object):
"""
Log that an object has been successfully added.
The default implementation creates an admin LogEntry object.
"""
from django.contrib.admin.models import LogEntry, ADDITION
LogEntry.objects.log_action(
user_id=object.created_by.id,
content_type_id=ContentType.objects.get_for_model(object).pk,
object_id=object.pk,
object_repr=force_unicode(object),
action_flag=ADDITION
)
def log_change(object):
"""
Log that an object has been successfully changed.
The default implementation creates an admin LogEntry object.
"""
from django.contrib.admin.models import LogEntry, CHANGE
LogEntry.objects.log_action(
user_id=object.created_by.id,
content_type_id=ContentType.objects.get_for_model(object).pk,
object_id=object.pk,
object_repr=force_unicode(object),
action_flag=CHANGE,
change_message=_('Changed')
)
def log_deletion(object):
"""
Log that an object will be deleted. Note that this method is called
before the deletion.
The default implementation creates an admin LogEntry object.
"""
from django.contrib.admin.models import LogEntry, DELETION
LogEntry.objects.log_action(
user_id=object.created_by.id,
content_type_id=ContentType.objects.get_for_model(object).pk,
object_id=object.pk,
object_repr=force_unicode(object),
action_flag=DELETION
)
# -*- encoding: utf-8 -*-
# --------------------------------
# Ripped from somewhere on the net
# --------------------------------
from django.contrib import admin
from django.contrib.admin.models import LogEntry, DELETION
from django.utils.html import escape
from django.core.urlresolvers import reverse
class LogEntryAdmin(admin.ModelAdmin):
date_hierarchy = 'action_time'
readonly_fields = LogEntry._meta.get_all_field_names()
list_filter = [
'user',
'content_type',
'action_flag'
]
search_fields = [
'object_repr',
'change_message'
]
list_display = [
'action_time',
'user',
'content_type',
'object_link',
'action_flag',
'change_message',
]
def has_add_permission(self, request):
return False
def has_change_permission(self, request, obj=None):
return request.user.is_superuser and request.method != 'POST'
def has_delete_permission(self, request, obj=None):
return False
def object_link(self, obj):
if obj.action_flag == DELETION:
link = escape(obj.object_repr)
else:
ct = obj.content_type
link = u'<a href="%s">%s</a>' % (
reverse('admin:%s_%s_change'
% (ct.app_label, ct.model), args=[obj.object_id]),
escape(obj.object_repr),
)
return link
object_link.allow_tags = True
object_link.admin_order_field = 'object_repr'
object_link.short_description = u'object'
admin.site.register(LogEntry, LogEntryAdmin)
---------
models.py
---------
.
.
.
class MyModel(TraceableModel):
title = models.CharField(max_length=256)
duration = models.IntegerField()
.
.
.
--------
views.py
--------
def my_method(request):
.
.
.
request_params = dict([k, v] for k, v in request.POST.items())
request_params.update({'created_by': request.user.id})
.
.
.
This way you can access to django admin an see Admin > Log Entries
# -*- encoding: utf-8 -*-
from django.db.models.signals import post_delete, post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from django.db import models
from log.actions import log_addition
from log.actions import log_deletion
from log.actions import log_change
class TraceableModel(models.Model):
created_by = models.ForeignKey(User)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
@receiver(post_save)
def post_save_handler(sender, instance, created, using, **kwargs):
if isinstance(instance, TraceableModel):
if created:
log_addition(instance)
else:
log_change(instance)
@receiver(post_delete)
def post_delete_handler(sender, instance, using, **kwargs):
if isinstance(instance, TraceableModel):
log_deletion(instance)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment