Skip to main content

Object view tracker for Django

Project description

Copyright 2010 - 2013 Caramel (formerly uAnywhere). Released under the 3-clause BSD license.

django-viewtracker is a simple Django application to allow you to do view tracking on objects. The primary purpose of the module is so that a user can determine what objects they have already seen.

It contains some additional “smarts” for dealing with updates as well - so if you haven’t read it since an update, then you haven’t read it at all.

The module is generic, and can be applied to any model you like.

Unlike some other view tracking modules for Django, this one stores it’s data in a Model (instead of the session), and thus only works for users who are registered. Unregistered users won’t have any view tracking at all, and all objects will appear as read for them. The advantage of doing this is that view tracking works across all devices/browsers that someone uses.

Installation

Install the module with the normal sudo ./setup.py install.

Add viewtracker to your INSTALLED_APPS in the settings.py of your application.

You’ll need to ./manage.py syncdb so that viewtracker’s modules can be installed.

Now you’re ready to use it.

Design

The system has three levels of view tracking. It will check each of these in order to determine if an object has been viewed.

The first level is “all view” tracking. Your application may allow a user to mark all objects as read. This is checked first against the object’s modification time. When you mark everything as viewed, all other records of views for the user are deleted to save space.

The second level is “model view” tracking. Your application may allow a user to mark all objects of a particular type as read. This the second thing to be checked against the object’s modification time. When you mark all of a model as viewed, all other records of individual item views are deleted to save space.

The third level is “instance view” tracking. A user views an object, you would use this to mark it as having being viewed.

This means to determine if an object has been viewed, it goes through three levels of checks, each increasing in complexity. The viewtracker tables may become quite large.

Using

First, track views of your object in your view (normally object detail view):

from viewtracker.models import ViewTracker
from .models import Car


class CarDetailView(View):
    def get(self, request, object_id):
        # Get the instance of the object to view
        # (Though in reality you'd probably use the Django Generic CBVs instead
        # of this.)
        car = get_object_or_404(Car, id=object_id)

        # Create an instance of the tracker for this user
        # If they are anonymous, then everything is viewed.
        tracking = ViewTracker(request.user)

        # Mark the instance viewed by this user
        tracking.mark_instance_viewed(car)

        # Render the template to display the object.
        return render(request, 'my_app/car_detail.html', dict(car=car, user=user))

You can then look up if an object has some changed data. You could show this in a list:

from django_globals import globals as django_globals


class Car(models.Model):
    # ... other fields ..

    # Use the name "last_updated" as the app will automatically to use this
    # field name
    last_updated = models.DateTimeField(auto_now=True)

    def has_viewed(self):
        tracker = ViewTracker(django_globals.request.user)

        # Here we've manually supplied the updated field name.
        return tracking.has_viewed(self, updated_field='last_updated')

Then in the template, you would have something like:

{% for car in car_list %}
    {# ... #}
    <td>
        <a href="{{ car.get_absolute_url }}">Listing #{{ car.id }}</a>
        {% if not car.has_viewed %}
            <img src="{{ STATIC_URL }}img/new.png" alt="New!" />
        {% endif %}
    </td>
    {# ... #}
{% endfor %}

There are also some built-in views, which you can use for marking all objects read, or all instances of a model as read:

url(
    r'^cars/mark_all_read/$',
    login_required()(viewtracker.views.mark_model_as_viewed),
    dict(model=Car),
    name='mark_all_cars_as_viewed'
),

Then call it in your template with something like:

<form method="post" action="{% url 'mark_all_cars_as_viewed' %}">
    {% csrf_token %}
    <input type="submit" value="Mark all cars as viewed" />
</form>

Note that by default all objects will be “unviewed”, so when you first roll the application out, you may wish to set everyone as having viewed all objects up to a particular point in time.

Project details


Release history Release notifications | RSS feed

This version

1.2

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-viewtracker-1.2.tar.gz (5.8 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page