haven't seen any hacks around, so thought I'd better ask...
is there a way to get the "currently online users" in some way?
Something like: "if a user has done something in the last 2 minutes he's
considered online".
Or is this exactly what "last_login" can be used for?
Any hints greatly appreciated,
- bram
1) last_login isn't on by default. That's actually an unasked question
I've had -- are there examples that show this working?
2) last_login would presumably be set only on login, not on every
request. So this wouldn't be the field to use for this anyway.
3) I looked at django_session thinking that if you enabled
settings.SESSION_SAVE_EVERY_REQUEST it would give you a timestamp to
use for this functionality. But django_session only has an expire
date. If this gets updated every request (not sure if it does) you
could subtract the time in SESSION_COOKIE_AGE to get what you're after.
4) If you've got a profile model you could add a "last_seen_date" field
to that model and manually update it on each request. This would be
hard if you have many views so option 3 might be preferred.
I'd probably go with the 3rd option. But if that didn't work, maybe
look at writing my own session middleware that added new column to the
django_session table that was a last_modified field.
-Rob
On Jan 23, 1:18 pm, "Rob Hudson" <treborhud...@gmail.com> wrote:
> I don't have an answer but some thoughts...
Me, too...
> I'd probably go with the 3rd option. But if that didn't work, maybe
> look at writing my own session middleware that added new column to the
> django_session table that was a last_modified field.
I would add option #5: Write a custom middleware component to update a
last_accessed attribute for logged in users on every request.
http://www.djangobook.com/en/beta/chapter16/
Will.
If you have a lot of requests, I doubt you really want to update a
table on every request. Hitting the DB is somewhat expensive;
re-pickling a session on top of that is pretty pricey.
The attached file implements a (lightly-tested) middleware. It makes
a dictionary keyed by datetime down to an even minute. The value is a
Set of user_id's seen that minute. This dict is updated by a request
middleware. The dict has keys for ONLINE_MINUTES (the number of
minutes you consider a user to be "online") + 1 minutes. Every
ONLINE_MINUTES * PURGE_MULTIPLE minutes, it removes old minute keys
from the dictionary.
This allows fast updating no matter how many users you have, fast
counting, and fast eviction. A downside is that it Includes partial
minutes (i.e. 2 minutes would count up to users seen in 2:59, due to
minute rollover); I think this amount of slop is probably OK given the
reduction in maintenance cost. ;-)
You'll want to use OnlineUsers.get_online_user_ids() wherever you need
the list of IDs.
If you have multiple web servers, this problem gets more complicated
-- then you probably need to use the DB or some shared process.
Please test it out and tell me if it works. If you need to -list-
users rather than count them, you may wish to keep usernames or user
objects rather than user_id's. That's a pretty straight-forward
change if you want it.
Let me know if it's useful; I can post it somewhere for others...
Wow, thanks a lot!
I'll let you know how it goes!
- bram