1

This is my user model-

class CustomUser(AbstractUser):

  user_id = models.UUIDField(default=uuid.uuid4,editable=False,primary_key=True)
  username = models.CharField(max_length = 100,unique = True)
  friends = models.ManyToManyField('CustomUser',related_name="friend", blank= True)
  user_last_seen = models.DateTimeField(auto_now_add=False)

I am able to track the time when a user was last seen (whether they log out or not) using the following middleware:

class ActiveUserMiddleware(MiddlewareMixin):

  def process_request(self, request):
      current_user = request.user
      if request.user.is_authenticated:
        now = datetime.datetime.now()
        current_user.user_last_seen = now
        current_user.save(update_fields=['user_last_seen'])

And also able to show in my template that whether they are active at the current moment, or when they were last seen -

 {%if i.user_last_seen|timesince|upto:',' < "1 minutes" %}
 <td style="font-size:small; color:green;text-align:right;">
 Active Now
 </td>
 {%else%}
 <td style="font-size:small; color:gray;text-align:right;">
 {{i.user_last_seen|timesince|upto:','}} ago
 </td>
 {%endif%}

Along with this, I want to show the total number of users that are active right now, who are friends with a certain user. But I am having a hard time to understand how to do that exactly. I am still a beginner when it comes to Django, any suggestions or ideas would be really helpful.

  • THe `<"1 minutes"` will not work. This simply compares strings. So `"1 hour" < "1 minutes"`, so a person online will be active now. Furthermore the active user will always be online. – Willem Van Onsem Oct 15 '20 at 16:17

1 Answers1

2

You can count the number that are last seen less than one minute ago with:

from django.utils.timezone import now
from datetime import timedelta

active_users = CustomUser.objects.filter(
    user_last_seen__gte=now()-timedelta(minutes=1)
).count()

or the number of active friends:

from django.utils.timezone import now
from datetime import timedelta

active_friends = request.user.friends.filter(
    user_last_seen__gte=now()-timedelta(minutes=1)
).count()

you thus can use this in a view, or in a context processor to pass the number of active users to the template.

You can also define logic in the CustomUser to check if a user is active:

from django.utils.timezone import now
from datetime import timedelta

class CustomUser(AbstractUser):
    user_id = models.UUIDField(default=uuid.uuid4,editable=False,primary_key=True)
    username = models.CharField(max_length = 100,unique = True)
    friends = models.ManyToManyField('CustomUser', blank= True)
    user_last_seen = models.DateTimeField(auto_now_add=False)

    @property
    def recently_active(self):
        return self.user_last_seen >= now()-timedelta(minutes=1)
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • Your code is working like a charm. I realised that I missed a major aspect, I was actually trying to track the total number of online users that are friends with a certain user, not as a whole. How to find that out in the view along with the code you provided? I apologise for not updating the post earlier, I have updated now. – justbeingalearner Oct 15 '20 at 16:46
  • 1
    @justbeingalearner: see edit for the number of active friends. `request.user` is the logged in user. – Willem Van Onsem Oct 15 '20 at 16:52