Home > Blockchain >  Recording user activity in django?
Recording user activity in django?

Time:09-28

I have a project in which some user can perform CRUD activities. I want to record who did what and when. Currently, I am thinking of making a model

class UserAction(models.Model):
    user_id = models.CharField(max_length=100)
    action_flag = models.CharField(max_length=100)
    class_id = models.CharField(max_length=100)
    action_taken_at = models.DateTimeField(default=datetime.now())

and making a function that fills my UserAction table. Is there any better way to do this?

CodePudding user response:

app/models.py:

from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey

class Action(models.Model):
    sender = models.ForeignKey(User,related_name='user',on_delete=models.CASCADE)
    verb = models.CharField(max_length=255)
    target_ct = models.ForeignKey(ContentType, blank=True, null=True,
    related_name='target_obj', on_delete=models.CASCADE)
    target_id = models.PositiveIntegerField(null=True, blank=True)
    target = GenericForeignKey('target_ct', 'target_id')
    created = models.DateTimeField(auto_now_add=True)
    class Meta:
        ordering = ('-created',)

    def __str__(self):
        return self.pk 

app/admin.py

from .models import Action
admin.site.register(Action)

How you can use it ?
you can now import this models(Action) inside any of yours views.py. Example if you have a post and a user likes it.you can just write

Action.objects.create(sender=request.user,verb="likes this post",target=post)

and now when you look at your admin you will see that tartget_id=post.pk Here I assume that a user is authenticated and you can change it for your own.Happy coding!!!

CodePudding user response:

You can do it by creating a model in Models.py

class Auditable(models.Model):
ip = models.GenericIPAddressField(null=True)
user_agent = models.CharField(max_length=255, blank=True)
remote_host = models.CharField(max_length=255, blank=True)
created_at = models.DateTimeField(auto_now_add=True, blank=True, null=True)
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING, related_name="%(app_label)s_%(class)s_created_by", null=True, blank=True)  # this is for web user
modified_at = models.DateTimeField(auto_now=True, blank=True, null=True)
modified_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING, related_name="%(app_label)s_%(class)s_modified_by", null=True, blank=True)  # this is for web user

class Meta:
    abstract = True

def get_fields(self):
    list_fields = ['ip', 'user_agent',
                   'remote_host', 'created_by', 'modified_by']
    return [(field.verbose_name, field._get_val_from_obj(self)) for field in self.__class__._meta.fields if field.name not in list_fields and not
            (field.get_internal_type() == "DateTimeField" and
             (field.auto_now is True or field.auto_now_add is True)) and
            field.concrete and (not field.is_relation or field.one_to_one or
            (field.many_to_one and field.related_model))]

You can give any class name (i have given auditable). So all you have to do is pass this class (auditable) in your every model instead of models.Model

For Eg: class Student(Auditable):

By doing this it will add all the auditable fields records in every table you have created. Hope you may get your answer by doing this.

  • Related