Reputation: 563
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
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
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})
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
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}
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