How to get the first time a user logged in within 24 hours in django

In Django, we can get the time a user last logged in by using Auth.User.last_login. That is only updated when the user logs in using his username/password.

This would be useful for queries such as getting the number of new records since the last visit.

Users can log out and also login multiple times in a day, now I want to get the first time a user logged in, in a day and store it in a model in the db.

How do I achieve this functionality?

This seems to be an appropriate use of an authentication signal.

See Login and logout signals. You could write a receiver that gets called when the person logs in. That receiver can check to see if their “current login” date is the same date as “now”, and if it isn’t, update it.

(Note: Be aware of timezone issues - the idea is the same but the implementation of the solution is slightly different if you want this log to reflect the user’s “day” as opposed to a UTC day. And what if a person has changed timezones during a day? Or what about DST changes? Is this a 24-hour day or a calendar day? These items may or may not affect how you wish to handle this.)

1 Like

Thanks for your response.
It is a 24 hours day, let’s say a user logged in 6:00 pm, the next time i would want to see thier last login should be anytime they log in from 6:00 pm the next day. I don’t know if it’s possible to store this in my db.

I don’t really know how to go about writing the logic for the login and logout signal, Please if you can show me a code on how to achieve this, that would be really appreciated.

You would need a model to store it in. If you have a custom User model or a user profile model, you could add a field to either of them to store it. It’s a DateTimeField that you are saving.

Ok, so you would be fine with UTC dates.

You can subtract two datetime fields, the result is a timedelta object. If that object represents more than 24 hours, then you update your model with the current time.

See the docs at Signals | Django documentation | Django to get started.

1 Like

i have written this using the link - timedelta.object your refered me to

# Getting user last login date
last_login = request.user.last_login

# check if the current time is greater than the last time a user logged in
if (datetime.now(timezone.utc) - last_login).days > 1:
    print('24 hours have passed')
    print(last_login)
else:
    print(last_login)
    print('Date is within 24 hours!')

now i want to get the first time a user logged in, because whenever a user log out and in again, the last login become the current time and that is not what i want but rather the first time they logged in.

i tried doing this

# Getting user last login date
last_login = request.user.last_login.first()

but i got this error that says last_login has no Attribute "first"
i know what that means but i dont how any other way to get the first time they logged in.

Please how do i get this?

The “last_login” field doesn’t help you with your stated requirements.

You need to create something named like “daily_logon” DateTimeField in either your custom User model or your User profile model.

1 Like

Now i have a model LoginSessionsTrack that keeps track of any user that logs in and also a field daily_login in the custom_user_model that stores the time any user logs in. Now anytime a user logs in it updates the model and the field and also, i am getting the first time a user logs in using the first() method.

models.py

class User(AbstractUser):
    email = models.EmailField(unique=True, null=True)
    username = models.CharField(max_length=10000)
    verified = models.BooleanField(default=False)

    # This is the new daily_login field
    daily_login = models.DateTimeField(auto_now_add=False, null=True, blank=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []


class LoginSessionsTrack(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    daily_login = models.DateTimeField(auto_now_add=False, null=True, blank=True)

Views.py

def loginView(request):
    if request.user.is_authenticated:
        return redirect('core:index')

    if request.method == 'POST':
        email = request.POST.get('email').lower()
        password = request.POST.get('password')

        try:
            user = User.objects.get(email=email)
        except:
            messages.error(request, 'User does not exist')

        user = authenticate(request, email=email, password=password)

        if user is not None:
            login(request, user)
            request.user.profile.daily_login_earning =+ 100
            messages.success(request, f"Hi {request.user.username}, you just earned  100 Daily Login Points. Congratulations!")
            request.user.daily_login = datetime.datetime.now()
            request.user.save()

            LoginSessionsTrack.objects.create(user=request.user, daily_login=request.user.daily_login)

            daily_login = LoginSessionsTrack.objects.filter(user=request.user).first()
            try:
                last_user_login = daily_login.daily_login
            except:
                last_user_login = timezone.now()

            now = timezone.now()

            if now - timedelta(hours=24) <= last_user_login <= now:

                print("Date is still less than 24 hrs")
            else:
                print("Date is now greater than 24 hours")
                
                # Creating a new login session objects whenever a user logs in using the login form
                LoginSessionsTrack.objects.create(user=request.user, daily_login=request.user.daily_login)
                # Adding 100 Points to the logged in user daily_login_earning - but this doesn't add the second time a user logs in.
                daily_earning = request.user.daily_login_earning =+ 100

            return redirect('profile', request.user.username)
        else:
            messages.error(request, 'Username OR password does not exit')
        
        
    context = {'page': page}
    return render(request, 'userauths/sign-in.html', context)

Now, how do i get get the first time a user logs in everyday (the first time they log in after every 24 hours), because my current code only get the first objects of a logged in user and that is the very first time they log in. It doesn’t check to see if the time greater than 24 hours then get a new login objects for that new day.

Please pardon my english and don’t get tired of my question :pray:t6: :pray:t6:

From what I’m understanding what you’re asking for, you want to calculate the difference between the current time and the daily_login value for that User. If that difference is greater than 24 hours, then and only then do you write a new value to that field.
(This will have nothing to do with the LoginSessionsTrack model. That would not be involved here.)

yes that is what i want to do, please what’s the right way to achieve this?

I outlined the fundamentals above at How to get the first time a user logged in within 24 hours in django - #4 by KenWhitesell

Okay, let me try it. Hopefully i’d know how to write it

Give it a try, and if you get stuck, we’ll still be here.

1 Like

What are the two date time field that i would be subtracting, i guess one would be the last object from the LoginSessionTrack, how about the other?

I don’t know if i’m correct.

As defined earlier in previous posts -

If you say that This will have nothing to do with the LoginSessionsTrack model. does that mean that that i would have to check the diffrence between the current time and the daily_login which is a field in my custom_user_model?

If that’s so, then i can do this

current_time = timezone.now()
daily_login = request.user.daily_login

new_login_time = current_time - daily_login 
if new_login_time > timedelta(hours=24)
    LoginSessionsTrack.objects.create(user=request.user, daily_login=request.user.daily_login)
    print("You earned 100 point for logging in today")

based on what you said i should do here: :point_down:t6:

Yes, correct on both.

Additionally, you would want to update user.daily_login in the True case of that conditional to “restart” the 24-hour window.

1 Like

That Solved It and i understand now how everything is woking, Thanks alot for your time, i really do appreciate it. :pray:t6: :heart: