Eu Chi
Eu Chi

Reputation: 563

How to track actions made by user, even those made with AJAX?

In my website I am tracking any actions made by users, pages viewed one by one.

In some views, I do some ajax requests like:

def books_list(request):
    books_list = Book.objects.filter(published=True).order_by('-timestamp')
    if request.method == 'POST' and request.is_ajax():
         id_book = request.POST.get('id_book')
         try:
              book = books_list.get(id=id_book)
              book.delete()
         except Book.DoesNotExist:
              return JsonResponse({'error':True,'msg':'Book not found'})
    render(request,'book/books-list.html',context={'books_list':books_list})

Here'is a quick view of how it looks like:

*# analytics *
- / # the home page
- /books/ # visits list of books
- /books/ # He deletes a book
- /books/ # back to list of books

As you can see, When user deletes a book, tracking keeps the same URL /books/obviously, How can I have it like:

*# analytics *
- / # the home page
- /books/ # visits list of books
- /books/delete # He deletes a book
- /books/ # back to list of books

Do I need to create new view/url for the simple delete action?

Upvotes: 0

Views: 283

Answers (1)

A.Raouf
A.Raouf

Reputation: 2320

You have two ways of logging what users are doing It is based on what is the purpose of tracking, is it just for logging or will it be at your db, however first one can be parsed into db (no_sql) or (sql) too You can take this abstract answer and optimize it due to your business requirements and for your project needs

First way

views.py

from .utils import get_client_ip
DELETED_FILES_LOGGER = logging.getLogger("deleted_files")
def books_list(request):
    books_list = Book.objects.filter(published=True).order_by('-timestamp')
    if request.method == 'POST' and request.is_ajax():
        id_book = request.POST.get('id_book')
        try:
          book = books_list.get(id=id_book)
          book.delete()
          DELETED_FILES_LOGGER.debug(
            'DELETION: %s by %s at %s from IP Address %s' % (
                book.filename(), request.user,
                datetime.datetime.now(), get_client_ip(request)))

        except Book.DoesNotExist:
          return JsonResponse({'error':True,'msg':'Book not found'})
    render(request,'book/books-list.html',context={'books_list':books_list})

utils.py

def get_client_ip(request):
    """
    to get client ip request
    :param request:
    :return: ip <str>
    """
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip

Second way

models.py

from django.contrib.admin.models import LogEntry as AbstractLogEntry


class LogEntry(AbstractLogEntry):
    class Meta:
        proxy = True
        app_label = 'data'
        verbose_name_plural = 'Log Entries'
        permissions = (("add_log", "add log entry"),
                       ("delete_log", "delete log entry"),
                       ("change_log", "change log entry"),
                       )

    def __str__(self):
        if self.action_flag == 5:
            return ugettext('Download "%(object)s."') % {'object': self.object_repr}
        if self.action_flag == 4:
            return ugettext('Uploaded "%(object)s."') % {'object': self.object_repr}
        elif self.is_addition():
            return ugettext('Added "%(object)s".') % {'object': self.object_repr}
        elif self.is_change():
            return ugettext('Changed "%(object)s" - %(changes)s') % {
                'object': self.object_repr,
                'changes': self.change_message,
            }
        elif self.is_deletion():
            return ugettext('Deleted "%(object)s."') % {'object': self.object_repr}

views.py

def books_list(request):
books_list = Book.objects.filter(published=True).order_by('-timestamp')
if request.method == 'POST' and request.is_ajax():
     id_book = request.POST.get('id_book')
     try:
          book = books_list.get(id=id_book)

          book.delete()
          LogEntry.objects.log_action(user_id=request.user.id,
                                        change_message='Upload %s for category %s' % (
                                            book.filename(), book.category),
                                        content_type_id=ContentType.objects.get(model__exact='book').id,
                                        object_id=book.id,
                                        object_repr=request.user.username,
                                        action_flag=4
                                        )

     except Book.DoesNotExist:
          return JsonResponse({'error':True,'msg':'Book not found'})
render(request,'book/books-list.html',context={'books_list':books_list})

You can also add logging at the manager itself

class BookManager(models.Manager):
    def delete(self):
        # you logging as mentioned above
        super(BookManager).delete()
class Book(models.Model):
    .....
    ....
    objects = BookManager()

Upvotes: 1

Related Questions