ambitioninc/django-entity-event — pull request #1 by Wilduck (2014-11-25 07:25:33+00:00)
Title: Initial modeling

@robdmc @wesleykendall I've written and rewritten the API for accessing events more times than I'd like to count at this point. I wanted this to be a bit more complete before I made a pull request, but this is as far as I've gotten and it's time to have other eyes on this.

The models have all stayed exactly as we discussed when I was in town. While you're free to comment on them, what I'd really like comment on is the API for accessing events. The basic structure is as follows:

Any piece of code that would like to access events, needs to be associated with a medium. This can be an instance of the `Medium` model, or of a model that inherits concretely from `Medium`. These mediums will differ in what events they're interesed in, and how the consume them. To support these differences, we provide three different methods on the `Medium` class to access events:

1. The `Medium.events` method gets all events that some entity is subscribed to for this medium.

2. The `Medium.entity_events` method gets all the events a given entity is subscribed to. This could be used as the basis for getting newsfeed style events.

3. The `Medium.events_targets` method gets a set of pairs of events and the targets for those events (a list of all entities subscribed to that event for this medium). This can be used for bulk processing of events, such as sending email notifications.

Additionally, all of these methods support filtering of the underlying events based on the time of the event, and whether or not the event has been seen, with more basic filter possible.

The final key component of this api are the `Medium.followed_by` and `Medium.followers_of` methods. These methods control the behavior of the `only_following` flag on subscriptions. The default implementations have `followed_by` return the entities and sub-entities of the entities passed in, and `followers_of` return the entities and super-entities of the entities passed in. Additionally, these methods are designed to be as easy to override as possible, simply taking a (list of) entity(s), and returning a queryset of entities. A class that inherits from `Medium` concretely should be able to use all three of the above methods as expected by overriding only these two methods with custom following relationships.

I believe this api is flexible enough to support essentially any type of access a medium could realistically need. Obviously, it's possible that I'm missing something.

I'd also be interested in hearing of possible performance improvements. I've attempted to structure the code to not use too many queries, but I haven't carefully optimized it. There are definitely code paths that are inefficient, but I think they are the less common ones. I'd like to discuss this further. I'm not sure how much optimization is needed at this point though.

This pull request contains only a minimal amount of documentation and tests. I wanted to get input from both of you before I spent too much time on those things, although if this api looks decent, writing tests and docs should be pretty easy.