From 195acd42319989315b8b3745952911535dbf9672 Mon Sep 17 00:00:00 2001 From: Charley Walton Date: Mon, 10 Apr 2017 16:12:59 -0700 Subject: [PATCH] Adding markdown readme --- README.md | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..167b73b --- /dev/null +++ b/README.md @@ -0,0 +1,181 @@ +# django-papertrail + +![](https://raw.githubusercontent.com/FundersClub/django-papertrail/master/docs/logo.png) + + +An elegant solution for keeping a relational log of chronological events in a Django application. + +[![](https://img.shields.io/pypi/l/django-papertrail.svg)](https://pypi.python.org/pypi/django-papertrail) +[![](https://img.shields.io/pypi/v/django-papertrail.svg)](https://pypi.python.org/pypi/django-papertrail) +[![](https://circleci.com/gh/FundersClub/django-papertrail.svg?&style=shield)](https://circleci.com/gh/FundersClub/django-papertrail) + + +## Installation + +To install `django-papertrail`: +``` +$ pip install django-papertrail +``` + +To enable `django-papertrail` in your project you need to add it to `INSTALLED_APPS` in your projects +`settings.py` file: +``` +INSTALLED_APPS = ( + ... + 'papertrail', + ... +) +``` + + +After that, you should migrate: +``` +$ python manage.py migrate +``` + +## Using it + +``` +import papertrail + +########################################################################### +# Creating entries +########################################################################### + +# Basic usage. Timestamp defaults to now +papertrail.log('cache-flushed', 'Cache was flushed!') + +# Optional data +papertrail.log( + 'periodic-cleanup-ran', + 'Periodic cleanup task executed.', + data={ + 'success': True, + 'cleaned_objects': 100, + } +) + +# Optional targets +papertrail.log( + 'user-logged-in', + u'{} logged in'.format(request.user.get_full_name()), + targets={ + 'user': request.user, + } +) + +# Optional timestamp +papertrail.log( + 'user-joined', + 'User joined site', + targets={ + 'user': request.user, + }, + timestamp=request.user.date_joined, +) + +# Multiple targets +user1 = User.objects.get(...) +user2 = User.objects.get(...) +papertrail.log( + 'user-followed', + 'User followed another user', + targets={ + 'follower': user1, + 'following': user2, + }, +) + +########################################################################### +# Querying the papertrail +########################################################################### + +# Gettying all papertrail entries that points to user1, without taking +# into account the target relationship name +qs = papertrail.related_to(user) +entry = qs.first() +print '[{}] {} ({}) - {}'.format( + entry.timestamp, entry.type, entry.message, entry.data +) + +# Get all entry that points to both users +# (Will only return entries that have both user1 and user2 in their +# targets) +qs = papertrail.related_to(user1, user2) + +# Query specific relationships, such as user1 following user2 +qs = papertrail.related_to(follower=user1, following=user2) + +# Filtering entry by a specific type (or any Django ORM filter) +qs = papertrail.filter(type='user-followed') + +# And chaining +qs = papertrail.filter(type='user-followed').related_to(follower=user1) + +# Get all the users that have followed a specific user (user1). This might +# look a bit confusing at first, but can be very useful. +# The objects_represented filter allows filtering a given queryset to contain +# only elements that have a specific papertrail entry pointing at them. +all_users = get_user_model().objects.all() +users_who_followed_user1 = (papertrail + # Narrow down to only user-followed entries that followed user1 + .filter(type='user-followed') + .related_to(following=user1) + # Return a User queryset that only has the users for which we have a + # user-followed entry that has a followed target pointing at them + .objects_represented(all_users, 'followed') +) + +# objects_not_represented does the same, but returns a queryset that +# excludes any object that has a papertrail entry pointing at it: +# Get all users who never logged in +users_who_never_logged_in = (papertrail + .filter(type='user-logged-in') + .objects_not_represented(all_users, 'user') +) +``` + +## Admin integration + +`django-papertrail` provides a Django admin integration to both view entries +(simple Django admin Entry list, usually available under /admin/papertrail/entry/) +as well as a more advanced intergration for objects you want to keep track of. + +The advanced integration provides two useful functionalities: + +1) Change tracking - whenever an object for which the integration is enabled is + added/edited/deleted, a papertrail entry will be created +2) A convenient link to view all papertrail entries pointing to the object + being viewed as well as an integrated papertrail viewer: + +![](https://raw.githubusercontent.com/FundersClub/django-papertrail/master/docs/scrshots/admin-view-link.png) +![](https://raw.githubusercontent.com/FundersClub/django-papertrail/master/docs/scrshots/admin-viewer.png) + +To enable the integration, your `ModelAdmin` class needs to inherit from `AdminEventLoggerMixin`: + +``` +from papertrail.admin import AdminEventLoggerMixin + +class MyObjectAdmin(AdminEventLoggerMixin, admin.ModelAdmin): + pass + + # The admin papertrail viewer can have filters: + papertrail_type_filters = { + 'Login events': ( + 'user-logged-in', + 'user-logged-out', + ), + 'Social events': ( + 'user-followed', + 'user-unfollowed', + ), + } +``` + + +A viewer with filters would look like this: + +![](https://raw.githubusercontent.com/FundersClub/django-papertrail/master/docs/scrshots/admin-viewer-filter.png) + + +Maintained by [Eran Rundstein @eranrund](https://www.github.com/eranrund/)