update value certain time later using django appscheduler

I want to update a value every day at a certain time later.

I wrote my models and views looks like

models.py

class InvestmentRequest(models.Model):
user = models.OneToOneField(User, related_name=“investment_request”, on_delete=models.CASCADE)
profit = models.DecimalField(max_digits=15, decimal_places=2)
created_at = models.DateTimeField(auto_now_add=True)

def __str__(self):
    return f"{self.user.username}-{self.amount}"

def increase_balance(self, profit ):
    self.profit += decimal.Decimal(profit )
    self.save()

def save(self, *args, **kwargs):
    super().save(*args, **kwargs)

views.py

from apscheduler.schedulers.background import BackgroundScheduler

def roi_profit(request):
investment = InvestmentRequest.objects.get(user=request.user)
amount = 15
investment .increase_balance(amount)
return …

scheduler = BackgroundScheduler()
job = None

def tick():
print(‘One tick!’)
index(request=None)

def start_job():
global job
job = scheduler.add_job(tick, ‘interval’, seconds=20) # it can be 24 hours
try:
scheduler.start()
except:
pass

start_job()

I used here “appscheduler” library because my requirement is minimal, it’s not a complex configuration like celery.
Is there any way to run ‘roi_profit’ views at a certain time every day? Here ‘tick’ function runs normally because it is a normal function. But I can’t call the views function because it’s a required request. And without request, I can’t get any value from request.user. It’s necessary. So this way how I can update my model value at a certain time later every day. Over a couple of days I’m struggling with it but couldn’t find the exact solution.

Any suggestions will be appreciated. Thanks.

When you create a task that will run on the background, you don’t want to call a view function because of this:

So you need a function that will do something based on a user:

But if you need the user, which user do you need? One user, all users?
If you need a specific user: Get it by the id and pass that to the function.
If you need all users: query all of them and call your function inside a for-loop.

1 Like

If you want things to reliably happen on a schedule, it must be managed externally to your main Django application.

However, using this requires as much an understanding of things as celery does.

See GitHub - jcass77/django-apscheduler: APScheduler for Django - you should not be using this in a view, it needs to be an external process.

If you want this to work and be reliable, go with a more robust solution. Either use the combination of Celery and Celery Beats or create a custom django command that is scheduled with cron.

1 Like

Yes, exactly I need specific user details, and that logic I can write only in the view function. I want to update specific user data continuously, so in this case, If I pass any data to another normal function it won’t work because without request.user how I can update the value on that specific user. It’s a problem here.

Suppose I create another normal function named “x” and I pass the user id or any data to that function from my “roi_profit” view function. In this case, after receiving the data how I can update the data without request.user. Or think about How I can call a model function from this “x” normal function. Definitely investment .increase_balance(amount) This is the model function call process.

I hope you understand it.

You need to be more precise with what you’re asking for here.

When you say “continuously”, what exactly do you mean by this? When should this update process start? When should it stop? How frequently should it occur?

What affects whether you’re processing one user and not another? (In other words, aren’t you really trying to update all users, one at a time?)

Definitely, It will have a certain time like 24 hours later every day. And update process will start 24 hours later after creating the data by a particular user.

And this kind of logic is not a problem if I can update the data from a normal function.

Again, needing clarification here.

Are you going to be updating all users every day? Or just some users?

If only some users, what is the difference between the users you will be updating and those you won’t?

For the users being updated, does it need to be 24 hours after some event for each user, or can all users to be updated get updated at the same time?

If “24 hours” after some event is required, how accurate does that “24 hours” need to be? (Can it be 25 hours? 23?)

You can update the data from a normal function, just not on a scheduled, recurring basis without using something like Celery.

Yes, it will be updated for some users every day at the same time.

Suppose A user invested some amount and B user not. In this case, A user will get a return amount or profit every day 24 hours later. B user is not in this condition because B is not invested. But if B user invested later he/she also will include in the same condition. This is a major difference here. It’s not a big issue here. Already all of the logic I have developed and tested successfully. Here I just need the scheduling system.

No. The time will be fixed. 24 hours is fixed. No more or less. I searched all of question-related to this and got appschedule library because of its less configuration and fewer functionalities than celery. And for my program, I hope this library is enough.

I’m not clear on how to update data from the normal function. Does any clue, please?

This technically unachievable. There is zero chance that you’re going to be able to guarantee that any specific process is going to execute exactly 24 hours after the previous execution, or that you can sustain that across any number of arbitrary intervals with an indeterminate number of users at unscheduled times.

You need to rethink your approach here, including the fundamental assumptions behind your requirements.

What this is really sounding like is an X-Y Problem.

So let’s take a step back. What is the underlying objective for this process?

It seems the answer is not clear to you. It’s a very normal process everybody is doing through celery or any other third-party apps.

Suppose a user created data at t time and the data will start updating from t time to 24 hours once completed. And that is technically already doing several platforms. Just think about the following program and how does work it a certain time after.

If I want to write a complex logic like in a week 5 days data will update means 24/1 day means 1 time a day and 5 times in a week. after 5 times 2 days will sleep. (time.sleep or whatever) after completing sleep again will happen same things. What do you think? Is it possible technically?

I can also write the logic for when the time will start or when the data will update. But how does the work schedule here perfectly? The normal function is working well but not for the views function.

No, it more seems like the complexity of what you’re trying to do isn’t clear to you.

Those who are doing it understand that it’s not exactly 24 hours.

No, because you’re not taking into account all the various things that can and will go wrong with that.

At a minimum, you’re not accounting for cases where the server you’re running on reboots. Obviously, processes are not going to run during that time that the server isn’t running.

You’re also not accounting for more routine issues like Daylight Saving Time transitions.

You’re also not accounting for the time it takes for these processes to run. If the process is going to run exactly 24 hours after the previous process starts, your sleep time needs to subtract the processing time from the sleep schedule.

Also, keep in mind that the various sleep functions are defined as not being exact. They are “sleep for at least x” and not “sleep for exactly x”. There’s no guarantee that a sleep function is going to be called at precisely the time slept.

Like I said, there’s a lot more to this than may appear at first look.

So, assume your server has just been rebooted.

How do you know which data needs to be updated since the last time your process ran?

The user who submitted data and when he submitted data.
Suppose the user submitted amount = 10 and the submitted time was Jan. 20, 2023, 2:11 p.m.
Now need to calculate the time from the submitted time. Suppose the current time is 20, 2023, 10:11 p.m. - So How many hours already passed here? Ans: 8 hours. Catch up my fixed time is 20 hours. means that 20 hours later the amount value will update. amount = …
So the current time when will 21, 2023, 10:11 a.m… it will happen. And this way will work also for the next 20 hours later …

I’m not following your math here relative to a 24 day, at least as it applies to my question.

User A submitted a transaction at 2:11 PM. User B submitted a transaction at 2:17 PM. User C submitted a transaction at 2:25 PM.

The next day, the server goes down at 2:15 PM. It’s down until 2:30 PM.

When the server comes back up, how is it going to know that Users B and C need to be updated, but User A doesn’t?

And, how long can your server be down before something needs to fundamentally change with your calculation?

This is the exception case we can detect. Or what accuracy here, is not possible achieve it to technically?

Not like this will happen. If they (A,B,C) transaction means all of them to need to be updated. I didn’t find any challenge here If I am able to schedule it.
If they transaction means they need to be updated else not. It will not affect on the server if the server is down or not. Because it’s depending on my condition.

Please specifically identify how you are planning to detect this, including the duration.

But in the example I showed, A would have been updated before the server crashed. It’s only B and C that were supposed to have been updated - but couldn’t because the server was down.

So my question is, after the server comes back up, B and C should have been updated - but weren’t. How are you going to know that they need to be updated?

Now, this isn’t just some extreme exercise. Following this chain of thought through to its logical conclusions is actually leading you toward the proper answer for the issue you’re trying to address here.

I can write there any exception logic or normal logic if they are updated or not. But a major challenging fact is how the program will be scheduled, How to update the data from normal function.

Ok.

So, the general solution is to write a Django management command that identifies the users that need to be updated. You then either use Celery & Celery Beats or cron to schedule that command to run every minute. This will process all users whose “24 hour window” has expired in the past minute.

Or if I think the efficient way for a fixed time for example UTC or any timezone 2.00 pm or others instead of 24 hours? Should I also think about Django management or celery? I want to do the program very simply in an efficient way but not robust.

I’m not sure what you’re asking for here.

You’ve got two reliable methods for scheduling a recurring task

  • Celery and Celery Beat
  • Cron

(There are other external-to-Django task schedulers available as well, but I wouldn’t see the need to adopt one of those in preference to either one of these.)

You cannot appropriately or properly manage this from within your Django process.