Reputation: 371
I have a model "Grade" which has one field: "name". I also have an instance of this Grade. i.e "Grade One". Is there a way in which I can automatically update that particular instance to "Grade Two" and all it's other related models after a given time span (Let's say one year), and then after another year change it to "Grade Three" and so on?
Upvotes: 0
Views: 201
Reputation: 415
A better approach will be to replace the name field to a "class_of" field which holds the integer year in which the student is expected to graduate (eg "Class of 2020"). That way, whenever you do the calculation:
MAX_GRADE - (student.class_of - CURRENT_YEAR)
You will get the current grade. No need to run scheduled jobs and the like.
To make this even more elegant, after making the above change in the model, I would add the following into the model class:
# At the top of models.py:
from django.utils import timezone
# Elsewhere in your model:
MAX_GRADE = 12
# In your model
@property
def name(self):
return "Grade" + str(MAX_GRADE - (self.class_of - timezone.now().year))
That way, it will always display the correct grade when you call student.name. The downside is you'll have to start querying using class_of and it will be slightly less efficient if you're calculating grades for large groups of students. But it's worth it compared to setting up task schedulers and cron jobs and the errors they could cause if not managed correctly.
Upvotes: 1
Reputation: 5492
You can define async / periodic tasks using celery
With celery, you can set a task to be run at a certain time, so you can schedule a task to run exactly one year after the current time. Or if you prefer, you can schedule a periodic task to run everyday, go over Grade objects that are expired and update them.
Upvotes: 1