Timeline is a flexable event stream app that uses redis as the backend to keep things fast.
- make sure you have redis installed.
pip install django-timeline
(or clone the source from https://github.com/tiltshift/django-timeline)- add
timeline
to theINSTALLED_APPS
list in your project’s settings.py file.
First up you need to define an event type. Generally the best practice is to add an events.py
file in the
application related to the event you are creating, but you can define the event anywhere.
The following will walk you thorugh the steps needed to create a new event definition, add an event of that type, and then display the resulting event in a timeline (stream).
Here is a generic example for an event definition where a user is adding an item:
from django.contrib.auth.models import User
from timeline.base import EventType
from yourapp.apps.items.models import Item
class UserAddedItem(EventType):
slug = "user_added_item"
context_shape = {
"user": User,
"item": Item,
}
queryable_by = ["user", "item"]
As you can see the event definition—UserAddedItem
—is made up of the following:
slug
: a unique ID for the event typecontext_shape
: think of this as variables for your event type. This is the stuff you'll be storing for each event of this type.queryable_by
: these are the variables from the context_shape that can be used to find this event. We’ll go over this later on.
Next you’ll need to write some code to create actual event objects:
from yourapp.apps.items.events import UserAddedItem
def Add_Item(user, item):
# app code for adding the item here.
UserAddedItem({
'user': user,
'item': item
}).save()
This code is hopefully pretty self explanitory. To create an event of the type UserAddedItem
you pass your variables—user
and item
in this case—and then save the event.
Now that you've got an event saved, lets look at how to display it:
from timeline.base import Stream
events = Stream(request.user)
Also hopefully pretty simple. By default the stream will take the given query, request.user
in this case, and find all events where that query exists in the event type’s queryable_by
.
Stream can take any number of positional arguments and it will combine their streams.
It also takes a number of keyword arguments:
event_type
will return onlyEvents
for a given slug.limit
a number saying how manyEvents
should be included, defaults to 20.cluster
a boolean saying whether the data returned should be clustered, if it is than it yields a list ofEvents
, rather than discreteEvents
.
In your templates you use the render_event
template tag to render your events. Here is an example:
{% load event_tags %}
{% for event in events %}
{% render_event event %}
{% endfor %}
The last step is to add a template representing each of your event types. The app looks for templates using the event slug: events/event/user_added_item.html
would be the template you add for an event with the slug user_added_item
.
Here is what user_added_item.html
might look like:
{{ event.user }} added an item {{ item }}.
you can also access the query object that was used to look up this event with the {{ query_object }}
variable.